목차
산술 오버플로
산술 오버플로는 코딩을 하면서 정말 흔하게 접할 수 있는 오류이다.
(특히 C++, C에서 말이다. JAVA는 내가 안써봤고. 나머지 언어에서는 경험을 해본적이 없다.)
왜 산술 오버플로라는 오류는 흔하게 발생할까?
첫째로,
프로그램 언어는 따로 오버플로를 경고하지 않는다.
둘째로,
알고리즘을 확인하는 과정에서 논리에 집중하다 보면,
산술 오버플로를 신경쓰지 못하고 지나칠 수 있다.
그럼 산술오버플로의 사례를 살펴보자.
산술 오버플로의 사례
너무 큰 결과
C, C++, JAVA등 숫자 자료형이 크기가 제한 되어 있는 경우,
어떤 문제를 푼 결과값이 자료형의 한계를 넘어설 때 이 오류가 발생한다.
흔히 32비트 자료형을 습관적으로 사용하다가,
결과가 32비트 자료형을 넘는것을 인식하지 못하고 오류가 발생해버린다.
너무 큰 중간값.
예를 들어서,
이 수식을 보자.
a, b, c를 각각 100000, 100000, 50000
으로 정의했다 하자.
그럼 정답은 200000이다.
하지만, 이걸 32비트 정수로 정의 했다면,
a x b의 과정에서 32비트 자료형의 크기를 넘어가서
제대로 된 결과값이 나오지 못한다.
이 경우에는 28201의 값이 나온다.
무한대 값의 필요
특정 문제를 해결하다보면 무한대 값이 필요할 때가 있다.
오버플로를 조금이나마 줄이는 소소한 방법
64비트 정수형을 쓴다.
가장 간단하다.
어떤 계산의 결과가 32비트 정수를 넘어간다 싶으면,
64비트의 정수형을 쓴다.
계산 순서를 바꾼다.
위의 이 식에서도 바꿀 수 있다.
a x b를 먼저하는것이 아니라.
b/c를 먼저하고, a를 곱하면 답의 차이는 없지만 같은 결과를 얻는다.
이렇게 계산 순서를 바꾸는 것만으로도
메모리도 아끼고, 오버플로도 나지 않게 할 수 있다.
C, C++의 promotion에 관해서
C, C++에는 많은 자료형이 있다.
부호가 있고 없고도 나뉘고,
short, int, long등 다양한 정수형이 있다.
이는 계산시 각각 같이 계산되는 변수에 따라 자료형이 바뀌는데
이걸 promotion이라고 한다.
그럼 promotion은 어떻게 이루어지는지 보자.
- 실수와 정수의 계산 => 정수를 실수로 변환 후 계산
- 실수와 실수의 계산 => 더 큰 실수 자료형으로 변환
- 정수와 정수의 계산 => 더 큰 정수 자료형으로 변환
- 정수와 정수(둘다 int보다 작은 자료형)의 계산 => int형으로 변환
- 부호 없는 자료형과 부호 있는 자료형의 계산 => 부호 없는 자료형으로 변환
하나하나 살펴보자.
#include <stdio.h>
int main(){
int a = 4;
float b = 2.4;
double c = 9.6
long long d = 42;
short e = 12;
char f = 6;
unsigned int g = 1257
a / b // 결과는 4.0/2.4로 1.666666... 이다.
c / b // 결과는 4.0 이 수의 자료형은 double이다.
d + a // 결과는 46 이 수의 자료형은 long long이다.
f + e // 결과는 18 이 수의 자료형은 int이다.
a + g // 결과는 1261 이 수의 자료형은 unsinged int이다.
return 0;
}
'Algorithm' 카테고리의 다른 글
에라토스테네스의 체(2022.04.13) (0) | 2022.08.03 |
---|---|
컴퓨터 안의 실수 - 1(with. IEEE 754)(2021.07.02) (0) | 2022.08.03 |
자주 하는 실수들(2021.06.17) (0) | 2022.08.03 |
코딩의 중요성(2021.06.16) (0) | 2022.08.03 |
문제 해결 전략(2021.06.13) (0) | 2022.08.03 |