今天,我追踪了为什么我的程序会出现一些意外的校验和不匹配错误,在我编写的一些代码中,该代码以包括32位校验和值的格式对IEEE-754浮点值进行了序列化和反序列化(
Today I was tracking down why my program was getting some unexpected checksum-mismatch errors, in some code that I wrote that serializes and deserializes IEEE-754 floating-point values, in a format that includes a 32-bit checksum value (which is computed by running a CRC-type algorithm over the bytes of the floating-point array).
经过一番摸索之后,我意识到问题出在0.0f和-0.0f具有不同的位模式(分别为0x00000000和0x00000080(little-endian)),但是C ++相等运算符认为它们等效。因此,发生校验和不匹配错误是因为我的校验和计算算法获得了这两种位模式之间的差异,而我的代码库的某些其他部分(使用浮点相等性测试,而不是逐字节查看值)字节)没有区别。
After a bit of head-scratching, I realized the problem was the 0.0f and -0.0f have different bit-patterns (0x00000000 vs 0x00000080 (little-endian), respectively), but they are considered equivalent by the C++ equality-operator. So, the checksum-mismatch errors happened because my checksum-calculating algorithm picked up the difference between those two bit-patterns, while certain other parts of my codebase (that use floating point equality testing, rather than looking at the values byte-by-byte) did not make that distinction.
好吧,很公平-我应该比总会进行浮点相等性测试更了解。
Okay, fair enough -- I should probably have known better than to do floating-point equality testing anyway.
但是这让我开始思考,是否还有其他IEEE-754浮点值被认为是相等的(根据C ==运算符)却具有不同的位模式?或者换一种说法,==运算符如何精确地确定两个浮点值是否相等?新手我虽然在其位模式上执行了类似于memcmp()的操作,但显然比它更细微。
But this got me thinking, are there other IEEE-754 floating point values that are considered equal (according to the C == operator) but have different bit-patterns? Or, to put it another way, how exactly does the == operator decide whether two floating-point values are equal? Newbie me though it was doing something like memcmp() on their bit-patterns, but clearly it's more nuanced than that.
这是我的意思的代码示例,在
Here's a code example of what I mean, in case I wasn't clear above.
#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平等规则。
It uses the IEEE-754 equality rules.
- -0 == +0
- NaN!= NaN
- -0 == +0
- NaN != NaN
更多推荐
C ==运算符如何确定两个浮点值是否相等?
发布评论