Why does PHP's sprintf not round 5s reliably?

后端 未结 3 728
梦如初夏
梦如初夏 2020-12-11 14:25

I was relying on sprintf(\'%0.1f\', 2.25) === \'2.3\' but it turns out it comes in at 2.2!

In fact it seems random:

php >         


        
3条回答
  •  既然无缘
    2020-12-11 14:57

    As an explanation of why round can offer better results than a function not specifically designed for rounding, we need to consider the limits of the double precision floating point representation. Doubles can represent between 15 and 17 decimal significand digits. From the Wikipedia article on double precision:

    If a decimal string with at most 15 significant digits is converted to IEEE 754 double precision representation and then converted back to a string with the same number of significant digits, then the final string should match the original. If an IEEE 754 double precision is converted to a decimal string with at least 17 significant digits and then converted back to double, then the final number must match the original

    The implementation of round can and should make use of this to "do the right thing" in most cases.

    Example 1:

    outputs:

    2.05000000000000
    

    Example 2:

    outputs:

    2.0499999999999998
    

    This is just a demonstration the IEEE 754 behavior.

    I am going to guess (because I haven't read its implementation) that sprintf doesn't really try to do anything particularly intelligent with regards to rounding, whereas round probably tries to round "correctly" (per IEEE 754) with respect to the number of significant digits you asked for.

提交回复
热议问题