Edit report at http://bugs.php.net/bug.php?id=53918&edit=1

 ID:                 53918
 Updated by:         cataphr...@php.net
 Reported by:        exploringbinary at gmail dot com
 Summary:            printf of floating point variable prints maximum of
                     53 decimal places
 Status:             Wont fix
 Type:               Bug
 Package:            Math related
 Operating System:   Windows (32-bit system)
 PHP Version:        5.3.5
 Block user comment: N
 Private report:     N

 New Comment:

I'd just add this is not as simple as changing the MAX_FLOAT_PRECISION
define, as values larger than around 512 (the value of NUM_BUF_SIZE)
will result in a buffer overflow.


Previous Comments:
------------------------------------------------------------------------
[2011-02-06 19:15:40] exploringbinary at gmail dot com

"Current PHP behaviour is analogous with other programming languages"



Except, for example, the three that I mentioned: gcc C (glibc), Python
and Perl.

------------------------------------------------------------------------
[2011-02-06 18:25:35] il...@php.net

Current PHP behaviour is analogous with other programming languages.

------------------------------------------------------------------------
[2011-02-04 15:03:45] exploringbinary at gmail dot com

The formula tells you the number of leading zeros plus approximately 17,
which I agree applies for any decimal value that's not exactly
representable. And I agree that there are unlimited decimal values that
map to the same double, e.g. DBL_MIN = 2^-1022. But if you enter the
decimal value representing 2^-1022 in your source code, it maps directly
to 2^-1022 in a double -- all its digits are accurate so the formula
does not apply. In other words, I'm sure this "is actually exactly
represented in an IEEE double."



Uses of this are limited, and I already said I agree. But one use is my
C program that prints all the powers of two representable by a double,
using only double-precision arithmetic (see link above).

------------------------------------------------------------------------
[2011-02-04 14:23:20] cataphr...@php.net

> I'm not sure what that formula tells you. 2^-1022 has 1022

> decimal digits: 307 leading 0s followed by 715 other digits.



Yes, but not all digits are born the same.



The accuracy of the IEEE double that represents 2^-1022 is 323.607. That
means all the decimal digits beyond that could be wrong due to rounding
errors.



Eith uncertainty dx, Accuracy[x] is -Log[10,dx]. For accuracy = 323.607,
dx = 10^-323.607 = 2.470328229206*10^-324.



Which means that, unless you're sure your number is actually exactly
represented in an IEEE double (an unlikely scenario of application),
your IEEE double doesn't represent 2^-1022. It represents 2^-1022 ±
1.235164114603*10^-324.



You can easily see this with a small C program. Let's take our 2^1022,
which has a nice binary representation:



#include<stdio.h>

void main() {

        double u,v;

        u = 2.22507385850720138309023271733e-308; /* given with 30 digits */

        v = 2.2250738585072014e-308;              /* given with 17 digits */

        printf("%016llx %016llx\n",

                *((unsigned long long*)&u), *((unsigned long long*)&v));

}



This prints the same double in big-endian form:

0010000000000000 0010000000000000

------------------------------------------------------------------------
[2011-02-04 03:24:11] exploringbinary at gmail dot com

I'm not sure what that formula tells you. 2^-1022 has 1022 decimal
digits: 307 leading 0s followed by 715 other digits. 



As for 2^-1074, it only NEEDS 1 bit of precision. All 1074 of its digits
can be printed: 323 leading 0s followed by 751 other digits. (1074
digits would be the limit for a double.)



These articles might be of interest

 

http://www.exploringbinary.com/a-simple-c-program-that-prints-2098-powers-of-two/
(using gcc it will print all the powers of two to full accuracy, even
the subnormal ones)



http://www.exploringbinary.com/converting-floating-point-numbers-to-binary-strings-in-c/
(I use a limit of 1077 -- 1074 plus "0." and string terminator)



As for "Except for some exotic application that would that uses numbers
only in the domain of the numbers representable in the IEEE double...".
I don't disagree with that. But glibc lets you do it, as do Python and
Perl. If it's a killer to implement, don't bother. If it's as simple as
changing that constant from 53 to 1074, I say why not?

------------------------------------------------------------------------


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=53918


-- 
Edit this bug report at http://bugs.php.net/bug.php?id=53918&edit=1

Reply via email to