Lig*_*ica 14 c++ floating-point
我们都知道(对吗?!),不应该通过测试equality(operator==)来比较浮点值.
但是,如果我真的想确定两个是否float小号a和b是二进制的平等?如果他们不被允许为NaN(或其他"特殊价值"),这是"安全的"吗?我可以依靠operator==这种方式运作吗?
Ste*_*non 20
(假设IEEE-754表示)几乎,但不完全.如果你可以排除NaN,你仍然需要处理这个事实+0.0并且-0.0有不同的二进制编码,但是比较相等(因为两者都是零).
当然,C++不需要IEEE-754.所以严格来说,所有的赌注都是关闭的.
如果要检查(in)编码的相等性,请使用memcmp(&a, &b, sizeof a).
接受的答案忽略了一个非常重要的方面:扩展精度浮点.CPU可能正在使用超过存储大小的位大小进行计算.如果您使用,则尤其如此,float但也可以是double其他浮点类型.
为了显示问题,以下断言实际上可能会失败,具体取决于编译的完成方式以及芯片的行为方式.
void function( float a )
{
float b = a / 0.12345;
assert( b == (a/0.12345) );
}
Run Code Online (Sandbox Code Playgroud)
现在,在这个简化的例子中,它可能总是通过,但在许多情况下它不会.只需查看GCC Bug 323并查看有多少缺陷被标记为重复.这种扩展精度会给许多人带来问题,也可能会给您带来麻烦.
如果你需要保证你需要做的是做一个比较函数,它接受两个float参数并保证函数永远不会内联(存储的浮点数不受扩展精度的限制).也就是说,您必须确保实际存储这些浮动.还有一个名为"store-float"的GCC选项我相信哪个强制存储,也许它可以用在你的个人功能上.