|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2009-09-29 20:52 UTC] terrafrost at gmail dot com
Description: ------------ Displaying a float in base-10 when fractional values are involved is difficult, as per <http://php.net/float>. Even if fractional values aren't involved, displaying the float might still be problematic, if the number you're trying to display is to big to be stored in the mantissa of a floating point number. Problem is, floating point numbers aren't always displayed correctly, even if the mantissa can hold the number in question. For example, if you have a double precision floating point number, your mantissa has 53 bits. The following corroborates this: <?php $test = 1; $bits = 0; while (fmod($test, 2) == 1) { $test = 2 * $test + 1; $bits++; } echo $bits; ?> That, for me, displays 53. The problem occurs with anything utilizing 48 or more mantissa bits: <?php $bits = 0; while (true) { if (bcpow(2, $bits) != (string) pow(2, $bits)) { break; } $bits++; } echo $bits; ?> Reproduce code: --------------- <?php echo pow(2, 52); echo "\r\n"; echo 4503599627370496; echo "\r\n"; echo pow(2, 52) == 4503599627370496 ? 'equal' : 'not equal'; echo "\r\n"; echo pow(2, 52) == 4503599627370500 ? 'equal' : 'not equal'; ?> Expected result: ---------------- 4503599627370496 4503599627370496 equal not equal Actual result: -------------- 4503599627370500 4503599627370500 equal not equal PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2026 The PHP GroupAll rights reserved. |
Last updated: Wed Feb 18 16:00:02 2026 UTC |
My main question here is what exactly you think we can do about this? We aren't artificially limiting the precision. We work with the OS we are on. If you run your script on a 64-bit OS (Linux in my case) the output is: 4503599627370496 4503599627370496 equal not equal Which is what you are expecting, correct? Run it on a 32-bit OS (Mac OSX 10.5 in my case) and the output is: 4.5035996273705E+15 4.5035996273705E+15 equal not equal This, of course, is not unique to PHP. Try this Perl script on the same 32-bit box: print 2**52; print "\n"; print 4503599627370496; print "\n"; if (2**52 == 4503599627370496) { print 'equal'; } else { print 'not equal'; } print "\n"; if (2**52 == 4503599627370500) { print 'equal'; } else { print 'not equal'; } And the output is: 4.5035996273705e+15 4.5035996273705e+15 equal not equal So, you will be filing the same bug against Perl, I guess? And just for completeness, that Perl script on my 64-bit Linux box outputs: 4.5035996273705e+15 4503599627370496 equal not equal So, Perl is actually more broken than PHP here.