Jer*_*ner 7 c floating-point comparison equality ieee-754
今天我正在追踪我的程序为什么会出现一些意外的校验和错配错误,在我编写的一些代码中,这些代码序列化和反序列化IEEE-754浮点值,格式包含32位校验和值(计算出来)通过在浮点数组的字节上运行CRC类型算法).
经过一番头疼之后,我意识到问题是0.0f和-0.0f分别有不同的位模式(0x00000000 vs 0x00000080(little-endian)),但它们被C++相等运算符认为是等价的.因此,校验和不匹配错误的发生是因为我的校验和计算算法选择了这两个位模式之间的差异,而我的代码库中的某些其他部分(使用浮点相等测试,而不是逐字节地查看值) 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;
}
Run Code Online (Sandbox Code Playgroud)
SLa*_*aks 13
它使用IEEE-754相等规则.
-0 == +0NaN != NaN