2009-10-27 5 views

답변

6

첫째, 서명 계산에 오버 플로우가 잠시 UB 잊고과 2의 보수 기계의 전형적인 오버 플로우 행동을 고집,

둘째 C.에서 정의되지 않은 동작이 발생합니다 : 오버 플로우가 발생할 사실로 밝혀 " 첫 번째 피연산자에서 첫 번째 피연산자보다 더 큰 결과가 나오거나 두 번째 피연산자가 음수 인 첫 번째 피연산자보다 크면 결과가 "잘못된 방향"으로 이동합니다. 귀하의 경우

int one, two; 

int result = two - one; 
if ((result < two) != (one > 0)) 
    printf("overflow"); 
+1

'int result = two - one; '이 오버 플로우 (또는 언더 플로우)하면 Undefined Behavior 랜드에 있는데 아무 것도 일어나지 않을 수 있습니다. – pmg

+0

내 대답의 맨 처음 문장에서 명시 적으로 언급 한 내용이 있습니다. (비록 전통적인 의미에서 "언더 플로우 (underflow)"라는 용어는 여기에 적용되지 않습니다.) – AnT

+0

나는이 답변을 좋아하지만 주목할 것은 정의되지 않은 행동입니다. 결과가 '잘못된 방향'으로 '움직일'것이라고 가정하는 것이 안전한가요? –

1

더 높은 정밀도로 비교할 수 있습니다. 32 비트 정수라고 가정 해보십시오. 64 비트 정수로 승격하고 빼고 그 결과를 32 비트로 캐스팅 한 다음 64 비트까지 다시 비교할 수 있습니다.

언어가 ... 크기에 당신에게 어쩌면 int32_t<inttypes.h>에서 (C99)에서 int64_t을 보증을 제공하지 않기 때문에 내가 int으로이 방법을 수행하지 않을 것입니다.

Windows를 사용하는 경우 ULongSub() 등을 사용할 수 있으며 오버플로시 오류 코드가 반환됩니다.

+0

: 0x7fffffff - 나는 내지 0xFFFFFFFFFFFFFFFF 얻을 때문에 내가 오버 플로우를 볼 0x80000000에 = 0xffffffff를 에서 64 비트 (. 그것이 있어야를하지만 그건 잘못된 답이다). – Murph

+0

이것은 부호없는 수량만을 사용하여 실제로 작동한다는 것을 잊어 버렸습니다 ... – asveikau

10

에서

당신은 그런 일이 전에 overlow (또는 언더 플로우)를 잡을 필요가있다. 일이 생기면 미정의 행동 땅과 모든 내기는 꺼져 있습니다. 내가 32 비트이 경우 않으면

#include <limits.h> 
#include <stdio.h> 

int sum_invokes_UB(int a, int b) { 
    int ub = 0; 
    if ((b < 0) && (a < INT_MIN - b)) ub = 1; 
    if ((b > 0) && (a > INT_MAX - b)) ub = 1; 
    return ub; 
} 

int main(void) { 
    printf("(INT_MAX-10) + 8: %d\n", sum_invokes_UB(INT_MAX - 10, 8)); 
    printf("(INT_MAX-10) + 100: %d\n", sum_invokes_UB(INT_MAX - 10, 100)); 
    printf("(INT_MAX-10) + INT_MIN: %d\n", sum_invokes_UB(INT_MAX - 10, INT_MIN)); 
    printf("100 + INT_MIN: %d\n", sum_invokes_UB(100, INT_MIN)); 
    printf("-100 + INT_MIN: %d\n", sum_invokes_UB(-100, INT_MIN)); 
    printf("INT_MIN - 100: %d\n", sum_invokes_UB(INT_MIN, -100)); 
    return 0; 
}