2016-07-08 7 views
18

https://github.com/numpy/numpy/issues/6428에서 버그의 근본 원인은 simd.inc.src:543 일 때 컴파일러에서 !(tmp == 0.)tmp != 0.으로 최적화합니다.float == 및! =가 직접 대립하지 않는 경우

A comment은 "이들은별로 똑같지 않습니다"라고 말합니다. 그러나 세부 사항을 명시하지는 않습니다. NaN은 계속 언급되지만 테스트에서는 NaN이 0.과 비교되는 것으로 나타났습니다.

==!=이 모두 true/false를 반환 할 수있는 경우는 어떻게됩니까?

또는 다른 필드에 차이가 있습니다. 예. 동일한 진리 값을 가지지 만 int와는 다른 값을 반환합니다 (그러나이 경우에도 테스트 결과가 표시되지 않습니다) ?

+0

'f'가'NaN' 일 수 있으면'int'가 아닙니다. –

+0

Nan cant는 0이됩니다. 0은 Number이므로 NaN은 숫자가 아니기 때문에 의미가 없습니다. 그래서 당신이 이렇게하면'int a = 0;'a는 NaN입니까? – amanuel2

+2

내가 명백한 것을 놓치고있는 경우 실례합니다. 그러나 그 스레드에서 그 원인을 근본 원인으로 식별합니까? 내가 본 가장 가까운 참조는 "나는 추측 할 것"입니다. 어쨌든이 링크 된 버그는 더 가까워 보인다. https://github.com/numpy/numpy/pull/6438 –

답변

7

의견은 "이것은 완전히 똑같지 않다"고 말합니다. 그러나 세부 사항을 명시하지는 않습니다. NaN은 더 자세히 언급되어 있지만 테스트 결과 NaN이 0과 비교되는 것으로 나타났습니다.

== 및! = 모두 true/false를 반환 할 수있는 경우는 무엇입니까?

이 표준은 말한다 :

== (같음) 및 !=이 (같지 않음에) 운영자는 자신의 낮은 우선 순위를 제외하고는 관계 연산자 유사합니다. [...] 모든 피연산자 쌍에 대해 정확히 하나의 관계가 참입니다.

, 공동이 연산자의 피연산자로 허용되는 어떤 식 X 및 Y에 대해,

따라서 (C2011, 6.5.9/3 중점 첨가), (X) != (Y)는 같은 결과로 평가되어야 !((X) == (Y)). 실제로 그렇게하지 않는 것이 발견되면 그 결과를 산출 한 컴파일러는 그 점에서 적합하지 않습니다. 해당 부적합이 예상치 못한 경우 컴파일러에서 버그가됩니다.

또한 6.5.9/3은 다른 피연산자와 마찬가지로 NaN, 무한대 및 하위 정규어에도 적용됩니다. NaN은 다른 이유로 이러한 연산자와 관련하여 특별합니다. NaN은 자신을 포함하여 모든 피연산자와 부동 소수점을 비교합니다 (IEEE 의미를 가정 할 때). 링크 된 게시물에서

+1

좋아, 나는이 성서를 끝내기 위해 궁극적으로 [그들의 ​​성명서에 주석의 저자를 불러 내야한다] (https://github.com/numpy/numpy/issues/6428#issuecomment-231404458) 것처럼 보인다. –

+1

@ivan_pozdeev 코드가'-ffast-math' 또는 그와 같은 경우에 정확하게 컴파일되지 않을 수도 있습니다. – fuz

+1

@ivan_pozdeev, FUZxxl의 예는 컴파일러가 부적합하지만 버그가없는 경우입니다.이 옵션을 사용하면 부적합이 발생할 수 있음을 문서화했기 때문입니다 (또한 옵션을 통해 명시 적으로 동작을 설정해야하는 이유이기도합니다) . 인용 된 numpy 버그는 MSVC 빌드와 관련이 있으며 MSVC는 부적합하고 버그가있는 것으로 유명합니다. –

0

:

charris 10 월 9 일에 댓글을 달았 2015

나는 !(tmp == 0.)를 추측거야 꽤 같은 일을하지 않은, tmp != 0.에 최적화되어 있습니다.영업 이익으로

코멘트 :

저자는 그것이 추측하지만 그들은 !(tmp==0.)tmp!=0.가 동등하지 않은 것을 매우 긍정적이며, 그것은 상식 인 것처럼 그 표현 말한다

방법 우리는이 두 가지를 조화시켜야합니까?

분명히 그들은 논리적으로입니다. 그러나 구현 방식에서는 그렇지 않을 수도 있습니다. 컴파일러는 a == b 테스트와 마찬가지로 부정 결과가 뒤 따르는 !(a == b)을 구현할 수 있습니다. 또는 식을 최적화하여 직접 a != b을 테스트 할 수도 있습니다. 결과로 나오는 어셈블리 코드는 두 경우에서 다를 수 있습니다. 동일한 결과가 달성되어야하지만, 실행 시간은 다를 수 있습니다.

a != b이 실제로는 문자 조합이 다르다는 것과 컴파일러가 기술적으로 다른 것을 할 수 있다는 것과 동일한 결과를 가져와야한다는 것을 인정하는 것입니다. 다른 결과가 나타나는 경우 컴파일러에 버그가있을 수 있습니다.

+1

무슨 말씀 이시죠? 그들은 같은 결과를 반환해야합니다. CPU가 어떻게 작동하는지는 아무런 결과가 없습니다. 다른 것은 컴파일러 버그입니다. 그런 다음 "동일한 결과를 달성해야합니다 (반드시)해야하지만 실행 시간은 다를 수 있습니다." - 그렇게 많은 테스트가 실패하게 만들니까 ...? –

+0

@underscore_d OP가 잘못 해석 된 charis의 "which is not same same"라고 말하고 있습니다. charris는 구현상의 차이점에 대해 이야기하고 OP는이를 논리적으로 동등한 것으로 읽습니다. 이 모든 것은 실제로 관찰 된 결과의 차이에 의해 복잡해지며, 두 당사자의 기대에 반하는 것입니다. OP는 논리적 인 동등성이 charris의 의견을 기반으로 어떤 경우에 해체되는지 파악하려고합니다. 그러나 charris 코멘트는 두 테스트의 논리적 등가성에 관한 것이 아니라 테스트 결과 구현에 관한 것입니다. – AJNeufeld