我们可以依靠op==来对浮点值进行二进制比较吗?
Can we rely on op== to binary-compare floating-point values?
我们都知道(对吧?!)不应该通过检验相等性来比较浮点值(operator==
)。
但是如果我真的想确定两个float
, a
和b
是否二进制相等呢?如果它们不允许是NaN(或其他"特殊值"),这是"安全的"吗?我可以依靠operator==
以这种方式发挥作用吗?
(假设IEEE-754表示)几乎,但不完全是。如果可以排除nan,则仍然需要处理+0.0
和-0.0
具有不同二进制编码的事实,但比较相等(因为两者完全为零)。
当然,c++不需要IEEE-754。所以严格来说,一切都不确定。
如果您想检查编码是否相等,只需使用memcmp(&a, &b, sizeof a)
。
可接受的答案忽略了一个非常重要的方面:扩展精度浮点数。CPU可能正在进行比特大小超过存储大小的计算。如果您使用float
,则尤其如此,但double
和其他浮点类型也可以为真。
为了显示问题,下面的断言实际上可能会失败,这取决于编译的方式和芯片的行为。
void function( float a )
{
float b = a / 0.12345;
assert( b == (a/0.12345) );
}
现在,在这个简化的例子中,它很可能总是通过,但在很多情况下它不会通过。只要看看GCC Bug 323,看看有多少缺陷被标记为重复。这种扩展的精度给许多人带来了问题,也可能给您带来问题。
如果你需要一个保证,你需要做的是创建一个比较函数,它接受两个float形参,并保证该函数永远不是内联的(存储float不受扩展精度的限制)。也就是说,必须确保实际存储了这些浮点数。还有一个名为-ffloat-store
的GCC选项,我相信它可以强制存储,也许它可以在这里用于您的单个函数。
相关文章:
- dev如何在C++中比较二进制数
- C++ 将二进制字符串转换为整数或比较 2 个字符串以查找差异数
- 有没有测试比较二进制的东西?
- 在查找子集中元素和元素数量之间的二进制比较背后的逻辑是什么?
- 浮点数的二进制相等比较是否正确
- 使用OTool进行了重构代码的二进制比较
- 寻求GMP二进制搜索:如何使用MEMCMP比较两个GMP MPZ_T
- 迁移到 VS2013 比较运算符 错误 C2678:二进制"=="无运算符
- "二进制表达式的操作数无效..."尝试比较regex_iterators时
- 将二进制文件内容保存在字符串中,以便能够对其进行 md5 并在以后与其他文件进行比较
- 比较两个二进制数,得到不同的位
- C++ 集<>类对象。使用自己的比较器给出错误:C2804:二进制'operator <'参数过多
- 二进制比较操作的优雅方式
- 我该如何计算在二进制搜索树中进行的比较
- 二进制搜索和eps比较
- 二进制搜索c++与比较
- 如何分割一个二进制字符串来比较每个数字
- 如何将整数表示为二进制以便使用异或进行比较
- 我们可以依靠op==来对浮点值进行二进制比较吗?
- 二进制比较的结果简化为什么数据类型