Markus Knaup wrote: > PHP5 does not round correctly. > echo round(1.025, 2) . "<br />";
Note that this is the same behavior as C's printf. Also the shell's printf which makes that behavior available to the command line produces the same behavior. $ printf "%.2f\n" 1.025 1.02 But it just didn't seem satisfying to say that it isn't a bug in PHP because that is just the way floating point computer engines work. But that is basically the reason. That is the way floating point works on machines. But being unsatisfying I wanted to add some more information about the problem. For the underlying reasons you need to look at the encoded binary values. A typical issue is that exact terminating decimal fractions may not have an exact binary representation. Therefore converting from decimal to binary creates an error. 1.020 => 1.00000101000111101011100001010001111010111000010100011110101110... 1.025 => 1.00000110011001100110011001100110011001100110011001100110011001... 1.030 => 1.00000111101011100001010001111010111000010100011110101110000101... Since there are an infinite number of digits needed this can't be used without reducing the number of digits in the calculation. That means that floating point operations routinely introduce errors into calculations. As to the exact details of rounding fractional digits I have always avoided needing to know that information. I have avoided it because when I needed an exact value I knew about the problems and instead used scaled integers. And so I can't give a better explanation now. Only a recommendation to avoid it too. Remember that floating point is only an approximation of reality. For more exact answers you may want to use binary coded decimal or scaled integers. This example is a good one to show why floating point isn't used for monetary transactions. My personal history is with CAD/EDA software and in that problem domain most software uses scaled integers to avoid these types of errors. There have been recent changes in the way PHP handles rounding. The upstream PHP documentation lists: 5.3.0 The mode parameter was introduced. 5.2.7 The inner workings of round() was changed to conform to the C99 standard. In 5.3.0 and later (Sid or Squeeze) the mode parameter gives you some control over rounding. $ php -r 'echo round(1.025,2,PHP_ROUND_HALF_UP) . "\n";' 1.03 Also the default rounding mode has changed too. $ php -r 'echo round(1.025,2) . "\n";' 1.03 Hope that helps, Bob P.S. Here are some useful references. http://en.wikipedia.org/wiki/Double_precision_floating-point_format http://en.wikipedia.org/wiki/Floating_point#Rounding_modes http://en.wikipedia.org/wiki/Binary_numeral_system#Decimal http://en.wikipedia.org/wiki/Binary_numeral_system#Representing_real_numbers http://cs.furman.edu/digitaldomain/more/ch6/dec_frac_to_bin.htm http://www.exploringbinary.com/binary-converter/ -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org