When I set PHP's precision
setting to values 18
or higher (whether in php.ini
or at runtime), the round()
function yields unexpected results. Is this a bug; or what am I missing?
Results for e.g. rounding the float 12.4886724321
to 4
decimal precision are as follows:
14: 12.4887
...
17: 12.4887
18: 12.4886999999999997
19: 12.48869999999999969
20: 12.48869999999999969
21: 12.4886999999999996902
22: 12.4886999999999996902
23: 12.488699999999999690203
24: 12.4886999999999996902034
Test case as follows:
$floaty = 12.4886724321;
for ($i = 14; $i <= 24; $i++) {
ini_set('precision', $i);
echo ini_get('precision') . ': ';
echo round($floaty, 4) . "\n";
}
Even if I set my $floaty
to just 12.4
, I'll get 18: 12.4800000000000004
etc. for "extrapolated" decimals. What exactly is this twilight zone we're entering at precisions 18 or greater? I do know how to clean things up for output, but I'd like to know why this happens, and whether it's intended behavior.
Tested on PHP 7.0.2 @ W7x64 and PHP 5.6.8 @ CentOS 6.5 with identical results. number_format()
doesn't do this, suppose it's more blunt (or non-mathematical) in how it truncates the decimals.
EDIT: Seems to happen with all math ops? 1234.56 - 1233.03
iterated at different precisions:
12: 1.53
13: 1.53
14: 1.53
15: 1.52999999999997
16: 1.529999999999973
17: 1.5299999999999727
18: 1.52999999999997272