2016-07-13 9 views
5

I가하기의 C 식 (변수 32 비트 수레)부동 소수점 제로 C 구현에서 (IEEE 754 불변?)

float result = (x1 - x0) * (y2 - y0) - (x2 - x0) * (y1 - y0) 

가 가정 x0==x1y0==y1 (및 ==와 I 이진 의미 그 표현의 신원), 표현식이 반드시 0으로 평가된다는 사실에 의존 할 수 있습니까 (부동 소수점의 모든 비트는 0으로 설정 됨)? 즉, 다음 불변식이 항상 있다고 가정 할 수 있습니까?

memcmp(&a, &b, sizeof(float) == 0 => memcmp(a-b, (uint32_t)0, sizeof(float)) == 0 
0*a == 0.0 

모든 값이 유한 수 (아무 INFINITY 또는 NaN이) 있다고 가정하는 것이 안전합니다.

편집 : 답변에서 지적한대로 0을 곱하면 부호있는 0이 생성 될 수 있습니다. memcmp는 더 나은 질문을 설명하기 위해 호출로 대체 유형 캐스트 ​​: 나는 아직도 식의 결과가 FP-비교 규칙을 사용하여 0.0으로 동일 할 것이라는 사실, 즉 :

(result == 0.0) 

편집 1에 의존 할 수 있습니다.

P. 어떤 차이가 생길 경우를 대비하여 필자는 코드를 준수하는 C11 컴파일러로만 제한하려고합니다. 나는 또한 STDC_IEC_559 지원에 의존 할 의향이 있다면 내 도움이 될 것입니다.

+0

'y2 - y0'과'x2 - x0'도 유한하다고 가정 할 수 있습니까? –

+0

@OliverCharlesworth : 예. 그렇지 않은 경우 결과가 정의되지 않은 상태로 확인됩니다. – MrMobster

+0

어떤 유형이'a'와'b'입니까? uint32_t가 아닌 경우 코드에서 정의되지 않은 동작을 호출합니다 (유효 유형 규칙 위반). 그래서 표준에 의해 허용되는 것이 있습니다.'ZERO'와 동일합니다. – Olaf

답변

4

IEEE 754가 C 표준에 필요하지 않으므로 C11에 대한 언급은 혼란 스럽습니다.

즉, IEEE 374 32 비트 부동 소수점 숫자를 가정하고 x2y2 (무한 또는 NaN이 아닌 것 외에는)에 대한 가정을하지 않으면 결과의 모든 비트가 0이 될 것이라고 가정 할 수 없습니다 IEEE 754 숫자는 두 개의 0을 가지며, 하나는 음수이고 다른 하나는 양수이고, (y2 - y0) - (x2 - x0) 표현식이 음수이면 0을 곱한 결과는 음수 0이됩니다.

우리는이 짧은 예제를 테스트 할 수

#include <stdio.h> 
#include <stdint.h> 

int 
main(int argc, char **argv) 
{ 
    union { 
     float f; 
     uint32_t i; 
    } foo; 

    float a = 0; 
    float b = -1; 

    foo.f = a * b; 
    printf("0x%x\n", foo.i); 

    return 0; 
} 

결과 (내가 영리 컴파일러를 원하지 않기 때문에 더 최적화를 알 수 없음) :

$ cc -o foo foo.c && ./foo 
0x80000000 

아, 단지 "다른 말로"라는 질문의 두 번째 부분은 다른 질문이기 때문에 실제로는 다른 말로 인식되지 않습니다.

(*(uint32_t*)(&a) == *(uint32_t*)(&b)) 

-0 == 0 때문에 부동 소수점에 대한 a == b에 해당되지 않습니다 :

로 시작합니다. 그리고 그것으로, -0 - 0이 당신에게 -0을주기 때문에 가정의 다른 부분이 떨어져 나옵니다. 나는 동등한 숫자의 다른 뺄셈이 음수의 0을 생성 할 수는 없지만, 가능하지 않다는 것을 의미하지는 않는다. 표준이 모든 구현에서 뺄셈을 위해 같은 알고리즘을 적용하지 않는다는 것을 확신한다. 어떻게 든 서명 비트가 몰래 빠져 나올 수 있습니다.

+0

"음수 0"으로 잘 잡습니다. 나는 실제로 대답이 예 (당신의 것을 읽기 전에) 일 것이라고 추측 할 것입니다. –

+0

감사, 아트! 물론 IEEE 표준에 대한 언급이 다소 오도 된 것입니다. 내가 가장 관심을 가지는 부분은 일반적인 하드웨어에 대한 추가 신원 확인, 일반적인 C11 컴파일러로 작성해야하는지, 또는 수표를 안전하게 건너 뛸 수 있는지 여부를 아는 것입니다. 서명 된 제로 코멘트는 매우 유용합니다! 나는 '0 비트 패턴'0 대신 FP 비교를 0으로하는 것이 좋을 것입니다. 안전할까요? – MrMobster

+0

@MrMobster 부동 소수점 수를 0으로 비교하는 가장 안전한 방법은'a == 0.0'입니다. 이것은 a가 음수인지 양수인지에 관계없이 작동합니다. – Art