2014-11-02 8 views
3

0으로 나누기를 확인해야 할 필요는 없습니다. 나는 부정적인 것에 의한 분열을 점검하는 것을 들어 본 적이 없다!런타임 오류를 -1로 나누기

if(*y == 0) 
    return 0; //undefined 
else 
    return *x/*y; 

x, y 나는 관련성의 경우에이 내용을 포함, int32_t에 대한 포인터입니다. 런타임시

*x==0x80000000, *y==0xffffffff 경우, 나는 (엑스 코드에서) 오류를 얻을 :

EXC_ARITHMETIC (코드 = EXC_I386_DIV, 서브 코드 = 0x0으로)

모든 I 온라인으로 찾을 수 있습니다 제안이 그 제로에 의한 나눗셈이지만 위의 검사에서 볼 수 있듯이 디버그 창에서 볼 수 있습니다. 여기서는 그렇지 않습니다.

무엇이 오류의 의미이며, 어떻게 해결할 수 있습니까?

+1

'y == 0xffffffff' 인 경우, 주장하는대로 int32_t에 대한 유효한 포인터가 아닌 것 같습니다. –

+0

@ Paul 감사합니다 - 오타, 뜻은'* y'입니다 – OJFord

+0

[이유는 unsigned int 0xffffffff은 int -1과 같습니다] (http://stackoverflow.com/questions/1863153/why-unsigned-int-0xffffffff-is- 1과 같음)을 사용하여 숫자 표현에 대해 설명하고 다른 기계 아키텍처에서 표현이 다를 수있는 0과 음수와 같은 숫자가있는 방법에 대해 설명합니다. –

답변

12

2의 보수 표현은 비대칭입니다. 양수보다 음수가 하나 더 많으며 음수에 양수가 없습니다. 따라서 MIN_INT을 무효화하는 것은 정수 오버플로입니다 (여기서 MIN_INT은 1 비트 만 부호 비트이고 32 비트 정수는 0x80000000입니다).

MIN_INT/-1도 따라서 산술 오버플로입니다. 뺄셈에서 오버플로 (거의 확인되지 않음)와는 달리, 나눌 때 오버랩이 발생하여 트랩이 발생할 수 있으며, 분명히 그럴 수 있습니다.

기술적으로 말하면, 결과가 정의되지 않았기 때문에, 나누기 전에 MIN_INT/-1 오버 플로우 경우를 확인해야합니다.

참고 : 인텔 x64 아키텍처의 일반적인 경우는 분할 오버플 트랩 혼동 상응하여 Posix 신호가 정상적으로 "부동 소수점 예외"로서 간주된다 SIGFPE 인 0으로 나누는 정확히 동일 않는다 부동 소수점이 보이지는 않지만. 현재 Posix 표준은 실제로 "잘못된 산술 연산"을 의미하는 것으로 SIGFPE을 그립니다.

+3

그 대신에 무엇을 할 수있는 '모범 사례'가 있습니까? 예를 들어, 결과가 0인지, 또는 'INT_MAX'인지 또는 다른 것을 결정할 수 있습니까? – OJFord