|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2011-04-06 19:22 UTC] for-bugs at hnw dot jp
Description:
------------
When round() is called with 1 argument which value is between 1e15 and 2^53, round() returns non-rounded value even if the value has fractional part.
For instance, though 1e15 is exact number as IEEE 754 double precision, round(1e15+0.1) returns 1e15+0.1. I think 1e15 is better result.
Test script:
---------------
<?php
'ini_set("precision",18);
var_dump(round(1000000000000000.1));
Expected result:
----------------
float(1000000000000000)
Actual result:
--------------
float(1000000000000000.12)
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Wed Oct 22 09:00:01 2025 UTC |
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; }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 }}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.)I said round(1000000000000000.125,3) returns 1.0E+15, but that's not true: ECHO returns that. round() seems to work as I expect for this example if I show it with printf: <?php echo round(1000000000000000.125,3); // Prints 1.0E+15 ?> <?php printf("%.3f",round(1000000000000000.125,3)); // Prints 1000000000000000.125 ?> (Interestingly, printf("%.3f",round(1000000000000000.125,0)) prints 1000000000000000.125)