c - C == 运算符如何确定两个浮点值是否相等?

标签 c comparison floating-point equality ieee-754

今天我正在追踪为什么我的程序会出现一些意外的校验和不匹配错误,在我编写的一些序列化和反序列化 IEEE-754 浮点值的代码中,格式包括 32 位校验和值 (这是通过对 float 组的字节运行 CRC 类型算法计算得出的)。

经过一番摸索,我意识到问题是 0.0f 和 -0.0f 具有不同的位模式(分别为 0x00000000 与 0x00000080(小端)),但它们被 C++ 相等性视为等价-运算符(operator)。因此,校验和不匹配错误的发生是因为我的校验和计算算法找出了这两个位模式之间的差异,而我的代码库的某些其他部分(使用浮点相等性测试,而不是逐字节查看值) byte) 没有做出这种区分。

好吧,很公平——我可能早该知道无论如何都不能进行浮点相等性测试。

但这让我开始思考,是否还有其他 IEEE-754 浮点值被认为是相等的(根据 C == 运算符)但具有不同的位模式?或者,换句话说,== 运算符究竟是如何判断两个浮点值是否相等的呢?新手我虽然它在他们的位模式上做了类似 memcmp() 的事情,但显然它比那更细微。

这是我的意思的代码示例,以防我在上面不清楚。

#include <stdio.h>

static void PrintFloatBytes(const char * title, float f)
{
   printf("Byte-representation of [%s] is: ", title);
   const unsigned char * p = (const unsigned char *) &f;
   for (int i=0; i<sizeof(f); i++) printf("%02x ", p[i]);
   printf("\n");
}

int main(int argc, char ** argv)
{
   const float pzero = -0.0f;
   const float nzero = +0.0f;
   PrintFloatBytes("pzero", pzero);
   PrintFloatBytes("nzero", nzero);
   printf("Is pzero equal to nzero?  %s\n", (pzero==nzero)?"Yes":"No");
   return 0;
}

最佳答案

它使用 IEEE-754 等式规则。

  • -0 == +0
  • NaN != NaN

关于c - C == 运算符如何确定两个浮点值是否相等?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6259653/

相关文章:

c++ - Clang - 获取实际的函数指针声明回溯

floating-point - "bias value"是什么 float ?

php - 为什么 PHP 使用 Zend_Amf 将数字 16 转换为 float(6.1026988574311E_320)

c - 如何根据输入的数字将答案设为 float 或整数?

c - 获取网络时间协议(protocol) (NTP) 时间戳

c - 整数/结构数组结束?

c - 按顺序在处理器之间传递消息

c - 比较两个字符

c# - 为什么 List<string>.Sort() 很慢?

c++ - 以有效的方式逐字节比较数据(使用 C++)