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

 ID:                 54056
 User updated by:    mr_platelet+jin6vr at fastmail dot fm
 Reported by:        mr_platelet+jin6vr at fastmail dot fm
 Summary:            number_format returns an incorrect answer for
                     certain parameters
-Status:             Feedback
+Status:             Open
 Type:               Bug
 Package:            Strings related
 Operating System:   Linux
 PHP Version:        5.3.5
 Block user comment: N
 Private report:     N

 New Comment:

Arbitrary precision is not needed, because

in each of the two scripts, the numbers

generated using pow can be perfectly

represented as IEEE double-precision

floating-point numbers.



I'll add an extra line of code to the first

script in order to explain better what the

problem is.  Here's the new script.



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

<?php

$x = pow(2, -1074);



# new line of code here:

printf("This shows that \$x is not zero:\n  %.53e\n\n", $x);



$s = number_format($x, 1074, '.', ''); 



if(trim($s, '0') === '.') {

  print "\$s represents zero, which is wrong.\n";

}

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



On my system, the output of the script is:



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

This shows that $x is not zero:

  4.94065645841246544176568792868221372365059802614324764e-324



$s represents zero, which is wrong.

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



$s definitely should not represent zero,

because 1074 (the second argument of

number_format) is exactly the number

of decimal digits needed to perfectly

represent 2 to the power of -1074.



More generally, for any positive integer

n, the number 2^-n can be perfectly

represented in base 10 using n decimal

digits, as can be seen by considering the

following sequence:



2^-1 = 0.5

2^-2 = 0.25

2^-3 = 0.125

2^-4 = 0.0625

2^-5 = 0.03125

2^-6 = 0.015625

2^-7 = 0.0078125

2^-8 = 0.00390625

2^-9 = 0.001953125


Previous Comments:
------------------------------------------------------------------------
[2011-02-20 16:37:22] ras...@php.net

I'm not sure what you are expecting here. number_format() is not an
arbitrary 

precision function. You are limited by the double precision of your
operating 

system.

------------------------------------------------------------------------
[2011-02-20 14:33:45] mr_platelet+jin6vr at fastmail dot fm

The following script shows further problems with

number_format.



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

<?php

$count = 0;

$wrong = 0;



for($i = 319; $i <= 1074; $i++) {

  $s1 = number_format(pow(2, -$i), $i, '.', '');

  $s2 = bcpow(2, -$i, $i);



  $s1 = trim($s1, '0');

  $s2 = trim($s2, '0');



  $count++;

  $wrong += ($s1 !== $s2);

}



print "Number of calculations: $count\n";

print "Number of wrong answers: $wrong\n";

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



When I run the script, it prints:



  Number of calculations: 756

  Number of wrong answers: 756



Some extra information.  (1) When running

each of the 2 scripts I've supplied, I

used PHP's "-n" switch.  (2) Here is the

"configure" command I used when building

PHP:



  --prefix=/usr/local/php/5.3.5 --disable-all --enable-bcmath

------------------------------------------------------------------------
[2011-02-20 14:17:59] mr_platelet+jin6vr at fastmail dot fm

Description:
------------
In the script below, number_format returns a string

representing zero, which is quite wrong.

Test script:
---------------
<?php

$x = pow(2, -1074);

$s = number_format($x, 1074, '.', ''); 

if(trim($s, '0') === '.') {

  print "\$s represents zero, which is wrong.\n";

}



Expected result:
----------------
I expect to see no output.

Actual result:
--------------
The script outputs the following message:



  $s represents zero, which is wrong.




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



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

Reply via email to