今天,我被追查为什么我的计划是得到一些意想不到的校验和不匹配误差,在一些代码,我写的序列化和反序列化IEEE-754浮点值,在包括32位校验值的格式(通过在浮点数组的字节上运行CRC型算法来计算)。C ==运算符如何决定两个浮点值是否相等?
经过一番摸头之后,我意识到问题是0.0f和-0.0f分别具有不同的位模式(分别为0x00000000和0x00000080(little-endian)),但它们被认为是C++平等的运营商。所以,校验和不匹配错误发生是因为我的校验和计算算法找出了这两个位模式之间的差异,而我的代码库的某些其他部分(使用浮点相等性测试,而不是逐字节地查看值)字节)没有做出区分。
好了,很公平 - 我应该知道更好,而不是做浮点平等反正测试。
但是,这让我思考,是否有其他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;
}
http://how-to.wikia.com/wiki/Howto_compare_floating_point_numbers_in_the_C_programming_language仅供参考,使用的ε是向前浮法比较的方式。不是在话题上,而是有用的知道。 – darvids0n 2011-06-07 01:10:08
NaN的可能(可能取决于编译器)会有两种方式。由于存在大量可能的NaN(单精度为2^24-1),它们在内存中也可能不同。 – ughoavgfhw 2011-06-07 01:19:30