최윤수 님이 쓰신 글 :
: int a = 1, b = 0;
: a = a / b;
:
: 0 아닌 정수를 0 으로 나누면 예외가 나도
:
:
: int a = 0, b = 0;
:
: a = a / a;
:
: 정수 0을 0으로 나누는건 0 이되야 하는데
: 왜 예외가 발생하죠?
답변:
두개의 정수 a를 b로 나눈 결과를 아래와 같이 x 라고 식으로 표현해 봅시다.
a / b = x
위 식을 다르게 표현하면 아래와 같은 방정식 형태로
bx = a
로 쓸 수 있죠?
a와 b를 0으로 대입해 보면...
0 곱하기 x = 0
이 되는데...
위 식을 만족하는 x는...
0 에다 0을 곱하든, 어떤 음수를 곱하든, 어떤 양수를 곱하든...
결과는 0이 되니까. (특정할 수 없는 무한수)
x 의 값을 딱 이거라고 특정할 수 없는 불능 상태가 되잖아요.
정수의 분수형태는 쉽게 풀어쓰면 정수인 몫을 구하는 거고
몫을 특정할 수 없는 불능상태가 되니까 CPU가 예외를 던지는 거죠.
수학적으로 풀어 보니까 쉽게 이해되죠?
하드웨어적으로 Exception 을 지원하지 않는 간단한 구조의 CPU인 경우에는
플래그 레지스터에 오버플로 비트를 셋팅하고 몫의 값을 정의되지 않은
쓰레기 값으로 처리하는 경우도 있습니다. (예를들면 8051)
이런 경우에는 CPU가 하드웨어적으로 Async 폴트 발생을 지원하지 않기 때문에
런타임 Divide by zero를 지원하게 하려면, 나누기 연산후 OV 플레그를 체크해서
소프트웨어적으로 예외를 던지는(Sync type Exception) 코드를 생성하도록
컴파일러를 만들어야 합니다.
정수의 경우에는 그렇고...
실수에서는...
컴파일러의 종류, 버전에 따라서...
X87 프로세서가 예외를 던지게 설정하기도 하고.
예외를 던지지 않고 좀 더 수학적으로...
nan, ind, 1.#INF, -1.#IND
등으로 표현해서 처리할 수 있도록 하기도 합니다.
수학적인 표현을 써서 처리할 것이냐
아니면 X87프로세서가 예외를 던지게 할 거냐는...
X87 프로세서의 마스크 비트를 설정해서 동작방식을
어떤 식으로 설정하는 가에 달려 있습니다.
이를테면...
VC++ 컴파일러는 예외를 던지지 않고
좀더 우아하게 수학적인 표현을 사용해서 처리하도록 하기 위해
플로팅 포인트 연산 예외를 발생시키지 않도록 X87 프로세서 마스크 비트를 설정한
상태로 사용하고 있음.
|