浮点等于的意外结果

问题不在于为什么0.1 + 0.9不等于1.0 。 它关于等于的不同行为。

有人能解释为什么下面的例子有不同的作

 float q = 0.1f; float w = 0.9f; float summ = q + w; q + w == 1.0f; // False summ == 1.0f; // True 

为什么operator ==工作方式不同?

问题是由于中间计算以更高的精度执行,并且在每种情况float转到float精度的时间规则是不同的。

根据文件

默认情况下,在x86体系结构的代码中,编译器使用协处理器的80位寄存器来保存浮点计算的中间结果。

…编译器对float类型的变量进行舍入,以便为赋值和强制转换的正确精度以及何时将参数传递给函数“

float summ = q + w是一个赋值,因此舍入到最近的float ,在本例中为1。

q + w == 1.0f既不是q + w == 1.0f ,也不是函数调用,因此加法的结果仍然是扩展精度浮点数,它接近但不等于1。

进一步了解IL:

summ存储在float32类型的本地中

 IL_000d: ldloc.0 IL_000e: ldloc.1 IL_000f: add IL_0010: stloc.2 

q + w == 1.0f使用的q + w == 1.0f的结果不是; 它直接用于比较

 IL_0011: ldloc.0 IL_0012: ldloc.1 IL_0013: add IL_0014: ldc.r4 1. IL_0019: ceq 

大概是在本地存储summ意味着它失去了足够的精度,它变得等于1.0f