我一直认为,NAN
通过
x!=x
或
std::isnan(x)
但是,gcc 为两个版本提供了不同的汇编程序 (live on godbolt.org):
;x!=x:
ucomisd %xmm0, %xmm0
movl $1, %edx
setne %al
cmovp %edx, %eax
ret
;std::isnan(x)
ucomisd %xmm0, %xmm0
setp %al
ret
但是,我很难理解这两个版本。我天真的尝试编译 std::isnan(x)
会是:
ucomisd %xmm0, %xmm0
setne %al ;return true when not equal
ret
但我一定遗漏了什么。
x!=x
版本可能缺少优化(编辑:可能是 regression in gcc-8.1 )。
最佳答案
x!=x
的结果是由于 regression introduced to gcc-8 , clang 为两个版本生成相同的汇编程序。
我对方式的误解ucomisd
@tkausl 指出正在运行。这个操作的结果可以是:
unordered < > ==
ZF 1 0 0 1
PF 1 0 1 0
CF 1 1 0 0
在 ucomisd %xmm0, %xmm
的情况下,只有结果“无序”和“==”是可能的。
NaN
的情况是无序的,为此 ZF 的设置与 ==
的情况相同。因此,我们可以使用标记 PF
和 CF
来区分两种可能的结果。
关于c++ - 了解 std::isnan 的编译结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51294168/