我知道使用 ==
检查浮点变量的相等性不是一个好方法。但我只想通过以下语句知道这一点:
float x = ...
float y = x;
assert(y == x)
由于 y
是从 x
复制的,那么断言是否正确?
原文由 Wei Li 发布,翻译遵循 CC BY-SA 4.0 许可协议
我知道使用 ==
检查浮点变量的相等性不是一个好方法。但我只想通过以下语句知道这一点:
float x = ...
float y = x;
assert(y == x)
由于 y
是从 x
复制的,那么断言是否正确?
原文由 Wei Li 发布,翻译遵循 CC BY-SA 4.0 许可协议
It won’t be true if x
is NaN
, since comparisons on NaN
are always false (yes, even NaN == NaN
).对于所有其他情况(正常值、次正常值、无穷大、零),此断言将成立。
避免 ==
对于浮点数的建议适用于 _计算_,因为浮点数在算术表达式中使用时无法准确表达许多结果。赋值不是计算,没有理由赋值会产生与原始值不同的值。
如果遵循标准,扩展精度评估应该不是问题。从 <cfloat>
继承自 C [5.2.4.2.2.8]( _强调我的_):
除了赋值和强制转换(删除所有额外的范围和精度)之外,具有浮动操作数的操作的值和经过通常算术转换的值以及浮动常量的值被评估为范围和精度可能大于要求的格式类型。
然而,正如评论所指出的那样,某些编译器、构建选项和目标的 情况可能 会使这自相矛盾地成为错误。
原文由 kmdreko 发布,翻译遵循 CC BY-SA 4.0 许可协议
3 回答1.3k 阅读✓ 已解决
1 回答1.1k 阅读✓ 已解决
4 回答843 阅读
1 回答919 阅读
1 回答954 阅读
1 回答719 阅读
1 回答819 阅读
除了 kmdreko 指出的
assert(NaN==NaN);
案例外,您还可能遇到 x87-math 的情况,即 80 位浮点数临时存储到内存中,然后与仍存储在寄存器中的值进行比较。可能的最小示例,当使用
-O2 -m32
编译时使用 gcc9.2 失败:Godbolt 演示: https ://godbolt.org/z/X-Xt4R
volatile
可能会被省略,如果你设法创建足够的寄存器压力来存储y
并从内存中重新加载(但足够混淆编译器,不要忽略比较全部 -一起)。请参阅 GCC 常见问题参考: