Edit report at http://bugs.php.net/bug.php?id=54479&edit=1
ID: 54479 Updated by: cataphr...@php.net Reported by: for-bugs at hnw dot jp Summary: round(1e15+0.1) returns 1e15+0.1 instead of 1e15 Status: Bogus Type: Bug Package: Math related Operating System: any PHP Version: 5.3.6 Block user comment: N Private report: N New Comment: PHP simplifies the round implementation by giving up more or less around when the accuracy falls below one. This is indeed a bit lazy even though the units digit is not accurate; without checking the algorithm/history maybe the purpose is to avoid the algorithm doesn't terminate due to adding numbers >=1 having no effect in the result. In any case, feel free to propose a patch. Previous Comments: ------------------------------------------------------------------------ [2011-04-16 20:39:18] exploringbinary at gmail dot com I would think since 1000000000000000.125 is exactly representable (53 bits), round(1000000000000000.125,3) would return 1000000000000000.125; but on PHP 5.3.5, it returns 1.0E+15. Compare this to printf("%.3f",1000000000000000.125), which prints 1000000000000000.125.(See http://bugs.php.net/bug.php?id=53918 for discussion on printing exactly representable values.) ------------------------------------------------------------------------ [2011-04-10 21:57:47] uncorrelated at yahoo dot co dot jp I'm suprized that floating point numbers of PHP doesn't support for IEEE 754. I'd like to confirm wheather PHP 5.3 supports for IEEE 754 or not. IEEE 754 ensures that 1000000000000000 differs from 1000000000000000.125 (see appendix). Then, IEEE 754 requires round(1000000000000000.125) returns 1000000000000000. In fact, the function of PHP 5.2.17 returns 1000000000000000. In spite of that, the function of PHP 5.3.6 returns 1000000000000000.125. It seems to be strange. If it is NOT a bug, PHP 5.3 doesn't support IEEE 754. Mr hnw may think that PHP should support for IEEE 754 as long as the system allows it, and the cutoff (precious) value shouldn't affect any operation but printing. Appendix: (Decimal)1000000000000000.125 is represented as the followings: Bits of Sign: 0 Bits of Exponent: 10000110000 Bits of Significand: 1100011010111111010100100110001101000000000000000001 (Decimal)1000000000000000 is represented as the followings: Bits of Sign: 0 Bits of Exponent: 10000110000 Bits of Significand: 1100011010111111010100100110001101000000000000000000 The significand of 1000000000000000.125 isn't same as that of 1000000000000000 (See the right edges of them). ------------------------------------------------------------------------ [2011-04-07 14:19:06] cataphr...@php.net If anything, the cutoff value is too high: The accuracy (effective number of digits to the right of the decimal point) of a double is given by 15.9546-log10(|x|) and: In[22]:= Solve[$MachinePrecision-Log[10, Abs[x]]==1.,x] 14 Out[22]= {{x -> 9.0072 10 }} ------------------------------------------------------------------------ [2011-04-07 01:52:10] for-bugs at hnw dot jp My test script seems to be wrong. How about next one? <?php ini_set("precision",19); var_dump(1000000000000000.125); // float(1000000000000000.125) var_dump(round(1000000000000000.125)); // PHP 5.3.6 returns float(1000000000000000.125) // PHP 5.2.17 returns float(1000000000000000) IEEE 754 double precision have 53 bit fractions, so 1000000000000000 and 1000000000000000.125 is exact number. This behavior is caused by ext/standard/math.c:160-163 /* This value is beyond our precision, so rounding it is pointless */ if (fabs(tmp_value) >= 1e15) { return value; } ------------------------------------------------------------------------ [2011-04-06 19:39:39] der...@php.net Floating point values have a limited precision. Hence a value might not have the same string representation after any processing. That also includes writing a floating point value in your script and directly printing it without any mathematical operations. If you would like to know more about "floats" and what IEEE 754 is, read this: http://www.floating-point-gui.de/ Thank you for your interest in PHP. . ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at http://bugs.php.net/bug.php?id=54479 -- Edit this bug report at http://bugs.php.net/bug.php?id=54479&edit=1