programing

두 인수 중 하나가 NaN인 경우 C/C++ <, <= 및 == 연산자가 true를 반환하는 원인은 무엇입니까?

randomtip 2023. 6. 10. 16:39
반응형

두 인수 중 하나가 NaN인 경우 C/C++ <, <= 및 == 연산자가 true를 반환하는 원인은 무엇입니까?

IEEE-754 부동 소수점 비교 규칙에 대한 내 이해는 다음을 제외한 모든 비교 연산자가!=둘 중 하나 또는 둘 다 인수가 NaN이면 false를 반환하는 반면,!=연산자가 true를 반환합니다.간단한 독립 실행형 테스트를 통해 이 동작을 쉽게 재현할 수 있습니다.

for (int ii = 0; ii < 4; ++ii)
{
    float a = (ii & 1) != 0 ? NAN : 1.0f;
    float b = (ii & 2) != 0 ? NAN : 2.0f;
    #define TEST(OP) printf("%4.1f %2s %4.1f => %s\n", a, #OP, b, a OP b ? "true" : "false");
    TEST(<)
    TEST(>)
    TEST(<=)
    TEST(>=)
    TEST(==)
    TEST(!=)
}

이렇게 하면 예상 결과가 출력됩니다. (NaN의 형식은 다음과 같습니다.)-1.$MSVC 런타임에서)

 1.0  <  2.0 => true
 1.0  >  2.0 => false
 1.0 <=  2.0 => true
 1.0 >=  2.0 => false
 1.0 ==  2.0 => false
 1.0 !=  2.0 => true
-1.$  <  2.0 => false
-1.$  >  2.0 => false
-1.$ <=  2.0 => false
-1.$ >=  2.0 => false
-1.$ ==  2.0 => false
-1.$ !=  2.0 => true
 1.0  < -1.$ => false
 1.0  > -1.$ => false
 1.0 <= -1.$ => false
 1.0 >= -1.$ => false
 1.0 == -1.$ => false
 1.0 != -1.$ => true
-1.$  < -1.$ => false
-1.$  > -1.$ => false
-1.$ <= -1.$ => false
-1.$ >= -1.$ => false
-1.$ == -1.$ => false
-1.$ != -1.$ => true

그러나 이 코드 덩어리를 모든 부동 소수점 계산이 수행되는 응용 프로그램의 내부 루프 깊이에 붙여넣으면 다음과 같은 설명할 수 없는 결과를 얻을 수 있습니다.

 1.0  <  2.0 => true
 1.0  >  2.0 => false
 1.0 <=  2.0 => true
 1.0 >=  2.0 => false
 1.0 ==  2.0 => false
 1.0 !=  2.0 => true
-1.$  <  2.0 => true
-1.$  >  2.0 => false
-1.$ <=  2.0 => true
-1.$ >=  2.0 => false
-1.$ ==  2.0 => true
-1.$ !=  2.0 => false
 1.0  < -1.$ => true
 1.0  > -1.$ => false
 1.0 <= -1.$ => true
 1.0 >= -1.$ => false
 1.0 == -1.$ => true
 1.0 != -1.$ => false
-1.$  < -1.$ => true
-1.$  > -1.$ => false
-1.$ <= -1.$ => true
-1.$ >= -1.$ => false
-1.$ == -1.$ => true
-1.$ != -1.$ => false

어떤 이유에서인지, 그.<,<=,그리고.==연산자 중 하나 또는 두 인수가 모두 NaN인 경우 예기치 않게 true를 반환합니다.게다가, 그들은.!=연산자가 예기치 않게 false를 반환합니다.

이 코드는 Intel Xeon E5-2650에서 실행되는 Visual Studio 2010으로 빌드된 64비트 코드입니다.사용._mm_getcsr()CSR 레지스터가 두 시나리오 모두 동일한 값을 가지고 있음을 확인했습니다.

이와 같은 부동소수점 수학의 행동에 영향을 줄 수 있는 것은 또 무엇일까요?

이 동작은 MSVC 컴파일러 옵션 때문에 발생하며, 이 옵션을 통해 컴파일러는 더 빠른 코드를 생성하기 위해 적절한 NaN 동작과 상관없이 비교를 수행할 수 있습니다.또는 를 사용하면 이러한 비교가 NaN 인수와 함께 표시될 때 예상대로 작동합니다.

언급URL : https://stackoverflow.com/questions/23641555/what-would-cause-the-c-c-and-operators-to-return-true-if-either-argu

반응형