두 인수 중 하나가 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
'programing' 카테고리의 다른 글
고유/임의 이름으로 파일 저장 (0) | 2023.06.10 |
---|---|
하나의 CSS 파일을 다른 파일에 포함하는 것이 가능합니까? (0) | 2023.06.10 |
명령줄을 사용하여 Firebase 데이터베이스 보안 규칙을 배포하는 방법은 무엇입니까? (0) | 2023.06.10 |
웹 API 인증 필터의 경우 내 클레임 ID가 항상 거짓인 이유는 무엇입니까? (0) | 2023.06.10 |
Firestore 문서에 타임스탬프 추가 (0) | 2023.06.10 |