问题不在于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
为什么运算符==
的工作方式不同?
答案 0 :(得分:2)
进一步了解IL:
summ
存储在float32
IL_000d: ldloc.0
IL_000e: ldloc.1
IL_000f: add
IL_0010: stloc.2
q + w
中使用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
。
答案 1 :(得分:2)
问题是由于中间计算以更高的精度执行,并且在每种情况下回退到float
精度的时间规则都不同。
根据the docs
默认情况下,在x86架构的代码中,编译器使用协处理器的80位寄存器来保存浮点计算的中间结果。
...编译器对类型
float
的变量执行舍入,以便为赋值和强制转换以及参数传递给函数时的正确精度“
float summ = q + w
是一项作业,因此四舍五入到最近的float
,在这种情况下为1。
q + w == 1.0f
既不是强制转换,也不是函数调用,因此加法的结果仍然是一个扩展的精度浮点数,它接近但不等于1。