은 결과의 크기보다 작 INT_MAX
INT_MIN
이상인지를 나타내는 가산 연산을위한 정수 오버플로 "플래그"를 계산하는 것. int
은 32 비트이고 2의 보수이며 부호있는 숫자의 오른쪽 시프트는 고위 비트를 복제하는 "산술"시프트라고 가정합니다. 안전한 가정은 없습니다.
x
과 y
의 부호가 같지만 결과의 부호가 반대이면 결과가 오버플로됩니다. 그것이 컴퓨팅의 전부입니다. 너무 복잡 할 필요가 없습니다. 우리가 원하는 경우
(x^y) < 0 && (x^result) < 0 /* (A^B)<0 iff A and B have opposite sign */
: 또한이 중요한 예외를 생성하지 않고 더 남았습니다 패리티 비트는이 표현은 원래의 코드와 같은 정신 부호 비트를 조작하여 작동합니다,가 없다고 가정
잘 정의 된 동작에 의존하는 것에 대해 까다로울 경우 x + y
은 불법 일 경우 결과가 오버플로 될 수 있습니다. C 표준을 따르는 시스템은 오버플로 (또는 자체 파괴 등)시 프로그램을 종료 할 수 있으므로 처음부터 그렇게하지 않아야합니다.
우리가 수행 할 테스트는
x + y > INT_MAX
x + y < INT_MIN
직접 x
와 y
사이에 안전 운전 없습니다 있습니다. 우리는 방정식의 반대편으로 움직여야합니다. 이것은 방정식의 반대와 빼기를 의미합니다. 그것은 INT_MAX
에서 양수를 빼거나 INT_MIN
에서 음수를 빼기 만 안전, 그래서 우리는 다음을 수정할 수 있습니다
y > INT_MAX - x
y < INT_MIN - x
그것을 할 수있는 가장 안전한 방법은 다음
x < 0? (y < INT_MIN - x) : (y > INT_MAX - x);
입니다 편집 : Woops, 나는 함수가 오버 플로우 플래그로 무엇을했는지 짐작하지 않았다. 오버플로가 없으면 결과를 반환하고 양수 오버플로가있는 경우 INT_MAX
을 반환하고 음수 오버플로가 발생하는 경우 INT_MIN
을 반환합니다. 다시 말해서, 그것은 덧셈을 포화시키는 것입니다. 그것이하는 방식은 약간 복잡한 데, 저자가 가지를 제거하는 데 어려움을 겪은 것처럼 보입니다. 그러나 오버 플로우는 일반적으로 발생하지 않으며 예측 가능한 분기는 많은 산술보다 저렴하므로 if … else
을 사용하여보다 직접적인 구현을 시도해 볼 가치가 있습니다.
두 쌍의 숫자 (하나는 오버플로, 하나는 오버플로)를 가져 와서 알고리즘을 통해 손으로 또는 디버거에서 각 op에서 일어나는 일을 볼 수 있습니까? – WhozCraig
그렇게 생각하지 않았습니다. 감사. Btw .. 오버플로는 어떻게 만드나요? – juice
가장 쉬운 방법은? '오버플로 (MAX_INT, MAX_INT) '해야합니다. 하지만이 모든 것은 32 비트 - 'int '플랫폼에서 실행되어야합니다. 그렇지 않으면 상관 없습니다. 그래도 태그에서 알 수있는 것처럼 보입니다. – WhozCraig