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:
<?=number_format(2.05,14); //give me 15 significant digits. Guaranteed to produce the orginal number
outputs:
2.05000000000000
Example 2:
<?=number_format(2.05,16); //give me 17 significant digits. Not guaranteed to produce the orginal number
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.