浮点数的二进制相等比较是否正确

Is binary equality comparison of floats correct?

本文关键字:是否 比较 二进制 浮点数      更新时间:2023-10-16

我正在研究不同的内存块操作函数,在基准测试期间,我注意到我对IsEqualRange(double* begin1, double* end1, double* begin2, double* end2)的实现比MSVC和GCC上的std::equals(...)要快得多。进一步的研究表明,双精度和浮点数不是memcmp的块,而是在一个一个接一个的for循环中。

在什么情况下,浮点数的二进制比较会导致不正确的结果?什么时候可以对浮点数/双精度数组进行二进制比较(相等)数组?还有其他我不应该使用memcmp的基本类型吗?

如果我是你,我要做的第一件事就是检查你的优化设置。

浮点数组使用 memcmp 是可以的,但请注意,您可以逐个元素==获得不同的结果。特别是,对于IEEE754浮点:

  1. +0.0 定义为比较等于 -0.0。

  2. NaN 被定义为比较不等于 NaN。

主要问题是nan值,因为它们永远不会等于它们自己。0(+0-0)也有两种表示形式相等但不等于二进制。

所以严格来说,你不能对它们使用memcmp,因为答案在数学上是不正确的。

如果您知道自己没有nan0值,则可以使用 memcmp

二进制比较对于许多实际应用程序来说精度太高。 例如,在javascript中,0.2/10.0 != 0.1 * 0.2 如果你有两个变量,它们最终都以非常非常轻微的舍入误差结束,尽管表示"相同"的数字,但它们将不相等。