Unexpected results for floating point equals

前端 未结 2 1102
遇见更好的自我
遇见更好的自我 2021-01-29 07:51

Question is not about why 0.1 + 0.9 is not equals 1.0. Its about different behaviour of a equals.

Can someone explain why examples below works

相关标签:
2条回答
  • 2021-01-29 08:27

    Looking further into the IL:

    summ is stored in a local of type float32

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

    the result of q + w used in q + w == 1.0f is not; it is used directly in a comparison

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

    Presumably the storage of summ in a local means it loses enough precision that it becomes equal to 1.0f.

    0 讨论(0)
  • 2021-01-29 08:30

    The problem is due to the fact that the intermediate calculations are being performed in a higher precision, and the rules for when to round back to float precision are different in each case.

    According to the docs

    By default, in code for x86 architectures the compiler uses the coprocessor's 80-bit registers to hold the intermediate results of floating-point calculations.

    ... the compiler performs rounding on variables of type float to the correct precision for assignments and casts and when parameters are passed to a function"

    float summ = q + w is an assignment, and hence is rounded to the nearest float, which in this case is 1.

    q + w == 1.0f is neither a cast, assignment or function call, so the result of the addition is still an extended precision float, which is close, but not equal, to 1.

    0 讨论(0)
提交回复
热议问题