php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #43053 [PATCH] Regression: some numbers shown in scientific notation
Submitted: 2007-10-20 15:41 UTC Modified: 2008-09-15 11:53 UTC
Votes:109
Avg. Score:4.5 ± 1.1
Reproduced:96 of 99 (97.0%)
Same Version:52 (54.2%)
Same OS:34 (35.4%)
From: owner at dragon-hearts dot net Assigned: dmitry (profile)
Status: Closed Package: Scripting Engine problem
PHP Version: 5CVS-2007-10-25 OS: Centos4
Private report: No CVE-ID: None
 [2007-10-20 15:41 UTC] owner at dragon-hearts dot net
Description:
------------
When using mathematical processes on numbers over 1 million the result comes out in scientific notation instead of as a normal integer.

Tested on PHP 5.2.1 it works as expected on 5.2.2 and above it doesn't.

I checked the change log and nothing is mentioned about this.


Reproduce code:
---------------
$var1=1;
$var2=7000000;
echo $var1*$var2;

Expected result:
----------------
7000000

Actual result:
--------------
7E+6

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-10-22 10:25 UTC] owner at dragon-hearts dot net
I tried it with small numbers too try this

$var1=0.00001;
$var2=1;
echo  $var1*$var2;


It prints out as 1.0E-5

Instead of 0.00001
 [2007-10-22 16:51 UTC] rbro at hotmail dot com
I am also running into this issue but only for certain float values.  The original example posted works correctly for me, but other float values are printed in scientific notation while others aren't.  It is related to the issue I reported in bug 42871 which was marked bogus.  I am running against php5.2-200710221430.

Reproduce code:
---------------
<?php
echo 1200000.00."\n";
echo 1300000.00."\n";
echo 1400000.00."\n";
echo 1500000.00."\n";

Expected result:
----------------
1200000
1300000
1400000
1500000

Actual result:
--------------
1.2E+6
1300000
1.4E+6
1500000
 [2007-10-25 13:41 UTC] jani@php.net
That last comment's script gives the same output for me, there's definately something strange going on here. :)
 [2007-11-12 10:19 UTC] tony2001@php.net
The explanation is quite simple: the number are floats.
There is not guarantee that "1200000.00" is actually represented and/or stored like that.
In this particular case, "1300000.00" is stored like "1299999.99", so there are no zeros to compress.
 [2007-11-12 15:32 UTC] owner at dragon-hearts dot net
If it's because they're floats why doesn't it happen in earlier versions of php i.e. 5.2.1? It makes migrating from php 5.2.1 to anything higher a nightmare since any site using these numbers will no longer work (i.e. mine didn't if you try and update mysql with what you expect to be a non scientific number i.e 1000000 and it tries 1E+6 it'll update it with 1 not 1000000) that causes real problems.
 [2007-11-13 13:54 UTC] rbro at hotmail dot com
Yes, I haven't upgraded to the latest PHP 5.2.x for the same reasons as it's causing similar issues for me with dollar amount calculations (e.g. bug 42871).  This change seems to have started in recent 5.2.x releases, but I don't recall it being on any changelog or announcement since it is causing backwards-compatibility issues with earlier PHP releases.
 [2007-11-17 20:35 UTC] owner at dragon-hearts dot net
Any idea when this might get fixed, since php5.2.5 has been released cpanel don't support 5.2.1 anymore hence it's not as easy to install 5.2.1 anymore and I'm stuck with 4.4.7 which won't be supported after December causing even more problems.
 [2007-11-21 17:33 UTC] theo at lomasdavies dot net
I am also experiencing this issue.

As a work around you can use sprintf or number_format to force it to display correctly.

not by any means a fix, but got me out of a jam.
 [2007-11-21 17:51 UTC] craig at craigmayhew dot com
Theo's work around does indeed work.

sprintf() or number_format() force the number to be displayed in an integer format.

Thanks Theo!
 [2007-11-25 01:22 UTC] owner at dragon-hearts dot net
I have something that is closer to a solution

If you replace the /zend/zend_objects.c file with the php-5.2.1 version before compiling php it fixes it.

I have tested on php 5.2.2 and php5.2.5 (I assume versions in between will work) and haven't noticed any ill effects but I am only configuring with the following 

./configure --disable-all --with-apxs2=/usr/local/apache/bin/apxs --prefix=/usr/local

So I don't know if any other modules will break (though I will test later). 

Since it's in the Zend folder should I report it to zend?
 [2007-11-30 22:56 UTC] ross at newgrounds dot com
I got bitten by this one too:

$rounded = floor(14700002 / 1000) * 1000;

in PHP 5.1.6, that yields: 14700000
in PHP 5.2.5, that yields: 1.47E+7

This is arguably acceptable behavior, but if this is the way it is, it 
should be a conscious decision, and documented.
 [2007-12-01 08:07 UTC] owner at dragon-hearts dot net
I could see it being desireable to have floats come out in normal or scientific format so maybe a php.ini setting would be in order for this.
 [2007-12-29 01:50 UTC] daniel at fanetworks dot net
I also noticed results coming as scientific notation for larger numbers in 5.1.6.

Honestly, it should always come out in interger format with an option to  return as notation.

Having data not return in a reliable format is a serious issue.

Its like $array = array(1=>2, 3=>4); sometimes returning with a serialized version of the array as a string instead of an actual array. Its hard to code when data is returning in an uncontrolled format :(
 [2008-01-18 21:42 UTC] nate at recoverydatabase dot net
We just got bit by this on one of our servers running Fedora 7 and PHP 5.2.4 installed via yum.  The others not causing any headaches are running Fedora 6 and PHP 5.1.6.

It's not just a display problem - we have a mysql database with very large values in the primary keys, and when this server tries to insert data, or display, or lookup information based on those values it fails miserably.

A php.ini option to disable the notation behavior would be nice.  As for right now I must get back to downgrading.  :(
 [2008-01-26 02:18 UTC] walter@php.net
This issue is still present in PHP 5.2.5 (FreeBSD). It only happens on some floats. 

If there is a reason for using E-notation in this case - which could be argued, although I feel changing past behavior is not necessary, especially as MySQL has trouble handling these values in common scenarios - it should be made consistent so people can depend on it and prevent problems by testing.

<?php

echo phpversion() . "\n";
echo 2700000.0;
echo "\n";
echo 2800000.0;
echo "\n";
echo 2900000.0;
echo "\n";

?>

devwh:~> php floats.php
5.2.1
2700000
2800000
2900000

test:~> php floats.php
5.2.4
2700000
2.8E+6
2900000

toms1:~> php floats.php
5.2.5
2700000
2.8E+6
2900000
 [2008-01-28 13:39 UTC] gcleaves at yahoo dot com dot au
Same problem:

PHP Version 5.2.4
Windows NT HGCT-SQL 5.2 build 3790
Apache 2.0 Handler
 [2008-02-09 13:20 UTC] lhfagundes at gmail dot com
This gets bad if the float is casted to string (which happens if it goes through requests):

$x = 1200000000.00;
echo $x . "\n";
echo (int)$x . "\n";
$x = "$x";
echo (int) $x . "\n";

In PHP 4.4.2 (I guess in earlier php5 too)

1200000000
1200000000
1200000000

now:

1.2E+9
1200000000
1
 [2008-03-04 23:07 UTC] tech at dragonara dot net
We have the same bug, and really - cPanel does not support 5.1 anymore, so we are really in stupid situation.
 [2008-03-06 15:56 UTC] rbro at hotmail dot com
I agree - to me, this is a BC break that wasn't listed on any changelog or announcement.  I have been holding off on upgrading my PHP version to anything later than 5.2.1 because of this issue.
 [2008-04-04 17:46 UTC] admin at vr-realty dot com
I had a working database for my office Stock Trading Pool when AAAHHHHkkk 1.23E+007. The non programmers there were all freaked the hell out. They thought E meant Error and that we had lost all of our money. trying to tell 70+ people, that haven't seen Scientific notation since they were in 9th grade, that it's not a problem and we will fix it was no easy task. By the time it was brought to my attention people had already started trying to figure out how to sue me for losing their money, yeah it was a mess. And they didn't know that what they see is just a thing for them to see and reference and really could be forgotten and not updated for days. 

anyways 

I wen through and changed the MySql DB from floats to VarChars. and type casted the $vars I pulled from the DB to float using

$curprice = (float)$price;
 and the ones that could be int like the number of shares
$curshares = (int)$shares;
 then I did the math
$total = (float)($price*$shares);

now the General population is feeling at ease and the death threats have subsided. I'm still trying to understand why Scientific notation would come into play.

maybe it sould be an obscure function like INT_TO_SCI($var) or num_to_sci($var) ..

like the automatic and natural way to have the numbers over millions sould be preserved as a whole long string no matter what the length with the option to convert it to scientific notation if that suits your needs.

my 2cents
 [2008-04-15 09:08 UTC] ali at adcworks dot com
I am receiving longs via SOAP responses which represent IDs of accounts. Due to some issue with PHP and long values when we retrieve accounts using the same IDs we receive, we get other peoples' accounts back - not good!

I have found the core problem and the snippet of code below shows that the correct ID of 285000000003622757 is transformed into the incorrect ID of 285000000003622752 (last number goes down 5).

<?php
$long = 285000000003622757;
function f0($long) { return $long; }
function f1($long) { return sprintf ( "%.0f", $long ); }
function f2($long) { return number_format($long, 0, '.', ''); }
?>
<h1>F0 (no formatting) </h1>
<?= f0($long) ?>
<h1>F1 (sprintf) </h1>
<?= f1($long) ?>
<h1>F2 (number_format) </h1>
<?= f2($long) ?>

OUTPUT
======

F0 (no formatting)
2.85000000004E+17
F1 (sprintf)
285000000003622752
F2 (number_format)
285000000003622752
 [2008-04-15 20:43 UTC] marek dot chodor at gmail dot com
on
PHP Version 5.2.6RC1-pl1-gentoo
and PHP 5.2.4 Fedora7
the same problem

$ php -r "echo 120000000;"
120000000

$ php -r "echo (double)120000000;"
1.2E+8

$ php -r "echo (int)(double)120000000;"
120000000

It could be related to this change in PHP 5.2.1:
# Changed double-to-string utilities to use BSD implementation. (Dmitry, Tony)
 [2008-04-15 22:37 UTC] rbro at hotmail dot com
Your examples work correctly for me in PHP 5.2.1, so I'm not sure if the issue was caused by change you mentioned or something else, but it definitely happens for me in PHP 5.2.2 and later.
 [2008-04-18 01:34 UTC] int-e at gmx dot de
Here's a patch that fixes the problem.

http://int-e.home.tlink.de/php/php-printf.patch

There are three changes here:
1) get rid of a hack in zend_dtoa() that sometimes kept trailing zeros (which caused the inconsistent behaviour between printing 1200000 and 1300000)
2) change php_gcvt() to switch to E format for large numbers if the number wouldn't fit into precision digits.
3) update a few tests to reflect the change to the precision semantics. I believe that in each of these cases, the test was flawed. Note that a precision of 14 (the default) means that 15 digit numbers should be printed in E notation, at least that's how I read the sprintf documentation.
 [2008-04-18 13:07 UTC] rbro at hotmail dot com
Thanks for your help - that definitely seems to fix the problem.  I manually applied your changes since I wanted to test it against the PHP 5.2.5 source, but I'm getting consistent output now when working with floats.
 [2008-06-30 14:38 UTC] admin at shadowops dot net
This bug is not limited to the Round() and related commands.

I have been hit by it and it has caused many issues with MYSQL and values entered into the DB.

1200000 in debug mode prints as 1.2E+6 this is why in the DB it simply +1 insted of 1200000
 [2008-07-02 04:43 UTC] int-e at gmx dot de
In the hope that this speeds up fixing the bug, here's a version of above patch that applies cleanly against php 5.2.6. The formatting of the code in question is different in the subversion trunk, but it's the same otherwise. At least that's how it was two months ago.

http://int-e.home.tlink.de/php/php-5.2.6-printf.patch

(use patch -p1 to apply)
 [2008-08-14 21:01 UTC] int-e at gmx dot de
That was just a small whitespace problem (5.2.6 had a lonely tab on an otherwise empty line in main/snprintf.c. it's gone in 5.3.0alpha1). Try this one.

http://int-e.home.tlink.de/php/php-5.3.0alpha1-printf.patch
 [2008-09-15 00:53 UTC] johannes@php.net
Dmitry, what's your opinion on this?
 [2008-09-15 11:52 UTC] dmitry@php.net
This bug has been fixed in CVS.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.


 [2008-09-15 11:53 UTC] dmitry@php.net
Thanks to int-e at gmx dot de
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 09:01:32 2024 UTC