php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #47304 typecast of numeric string to float produces strange result
Submitted: 2009-02-04 12:41 UTC Modified: 2013-01-08 07:29 UTC
Votes:25
Avg. Score:4.8 ± 0.6
Reproduced:24 of 24 (100.0%)
Same Version:7 (29.2%)
Same OS:15 (62.5%)
From: lennart dot vandendool at fonq dot nl Assigned: pajoye (profile)
Status: Wont fix Package: Scripting Engine problem
PHP Version: 5.2.9 OS: win32 only
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2009-02-04 12:41 UTC] lennart dot vandendool at fonq dot nl
Description:
------------
Typecasting or converting some numeric strings variables to a float value does not work as expected.

Reproduce code:
---------------
$var = (float)"-39.000";
var_dump($var);
$var = (float)"39.000";
var_dump($var);
$var = (float)"17.000";
var_dump($var);
$var = (float)"-17.000";
var_dump($var);
$var = "-39.000" + 0;
var_dump($var);
$var = "39.000" + 0;
var_dump($var);
$var = "17.000" + 0;
var_dump($var);
$var = "-17.000" + 0;
var_dump($var);

Expected result:
----------------
float(-39)
float(39)
float(17)
float(-17)
float(-39)
float(39)
float(17)
float(-17)

Actual result:
--------------
float(-38.:)
float(38.:)
float(16.:)
float(-16.:)
float(-38.:)
float(38.:)
float(16.:)
float(-16.:)

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-02-04 22:22 UTC] jani@php.net
Forgot this, output on my linux server using PHP 5.2.8:
float(-39)
float(39)
float(17)
float(-17)
float(-39)
float(39)
float(17)
float(-17)


 [2009-02-05 09:12 UTC] lennartvdd at mailordersolutions dot nl
I installed the latest version like you recommended (PHP version: 5.2.9-dev (win32 x86 VC6)). That fixed it.
 [2009-02-05 11:34 UTC] lennartvdd at mailordersolutions dot nl
For some strange reason the problem is reoccurring again with version 5.2.9-dev!

Reproduce code:
---------------
echo "PHP version: " . PHP_VERSION . "\n";
$var = (float)"-39.000";
var_dump($var);
$var = (float)"39.000";
var_dump($var);
$var = (float)"17.000";
var_dump($var);
$var = (float)"-17.000";
var_dump($var);
$var = "-39.000" + 0;
var_dump($var);
$var = "39.000" + 0;
var_dump($var);
$var = "17.000" + 0;
var_dump($var);
$var = "-17.000" + 0;
var_dump($var);


Actual result:
--------------
PHP version: 5.2.9-dev
float(-38.:)
float(38.:)
float(16.:)
float(-16.:)
float(-38.:)
float(38.:)
float(16.:)
float(-16.:)
 [2009-02-05 14:12 UTC] jani@php.net
Eh? How come it worked once but not after that? Can you reproduce this with totally different machine? (works fine still for me on all machines I have, and I have quite a few..)
 [2009-02-05 14:24 UTC] lennartvdd at mailordersolutions dot nl
Yeah weird huh?! I changed back to PHP version: 5.2.0. Float conversion works fine again now!

I'll try it on some different machines, but I won't have time to do that until next week, so you'll hear more from me then.
 [2009-03-20 15:58 UTC] pajoye@php.net
What is the last version working correctly?
 [2009-03-20 16:08 UTC] pajoye@php.net
What is the exact version of 2003, which processor do you use?

However it works for me with the US locale on XP SP2 (32bit), 2003 (x86), 2008 (x86 and x64), vista (x86 and x64).

C:\Users\pierre\Documents\test\php529-1>php 47304.php
PHP version: 5.2.9-1
float(-39)
float(39)
float(17)
float(-17)
float(-39)
float(39)
float(17)
float(-17)

 [2009-03-20 16:13 UTC] pajoye@php.net
For the record, other test cases in #47732 and #47716.

It would be interesting to see if 5.3.0 (you can fetch snapshot from http://windows.php.net) suffers from the same problem on the same host.
 [2009-03-20 17:08 UTC] codeslinger at compsalot dot com
Hi pajoye,
thank you for the response to bug #47716
you requested that future replies be here.

The interesting thing is that when you did a setlocale you got a result back...   but when I did it all I get is an empty string, I wondered about this at the time that I entered the bug but did not mention it because I figured the 18:0 vs 19.00 was sufficient.

and yes, as it states in that bug, the problem only occurs when a large complex program using lots of memory is running and then within that context you run the repro.  if you just do the repro script by itself with nothing else going on then it works just fine.


$arrMsgs[] = "Locale = ".setlocale(LC_ALL, "english-usa");

[0] => Locale = 


I will give 5.3 a try and see what happens.

Environment: For the testing, I am actually running windows 2000 in a vmware box under Ubuntu on a Pentium M.
 [2009-03-20 22:32 UTC] egorich at junik dot lv
Concerning bug #47732:

I was using PHP 5.2.6, and did not noticed that problem. It started just after an upgrade to 5.2.9-1. 

And now the strange thing:
I left home with my browser opened on a test script page

<?
echo ceil(3350/200);
?>

And it printed "16.:".
When I came back after 5 hours and hit refresh... It printed "17"! During that time nothing was changed in the server setup, php still is 5.2.9-1, etc...


My system:
Windows 2003 small business server SP2, x86
Apache 2.2
PHP 5.2.9-1
 [2009-03-20 22:44 UTC] egorich at junik dot lv
10 minutes passed and now I see "16.:" printed. Of course nothing is changed at that time on the server...
 [2009-06-08 09:47 UTC] egorich at junik dot lv
So, any solutions to this? 
The problem also arises when i try to convert string to double, like:
$amount = double($amount);
 [2009-06-22 03:47 UTC] ang dot chin dot han at gmail dot com
Originally from:

http://www.reddit.com/r/programming/comments/8tqpj/phpwtf_an_annoyance_
will_be_posted_each_day/c0aeg66

In short, in a Ubuntu Hardy 32 bit (64bit unaffected), 5.2.4 (with 
Ubuntu patches) a simple

  echo 1.0-0.5;

produces "0.0:" instead of "0.1" like in other platforms.

Not sure if it's the same bug as this is casting from float to string.
 [2009-06-22 16:21 UTC] ciudadsatan at hotmail dot com
The bug in Linux happens with
    echo 0.15-0.05;
 [2009-09-28 09:58 UTC] egorich at junik dot lv
Seems that it fixed with rolling back to php 5.2.5 to me.
 [2009-12-23 07:22 UTC] p dot klein at letsmakesense dot de
I experienced this issue using the number_format() and round()-function. My example page displays items in a price list and prices like '17' or '19' (only even numbers) were converted to '16.:' and '18.:'. The weird thing was that every fourth reload the prices were converted correctly to '17,00' and '19,00'. The situation improved after I calculated the floats with BCMath functions. Now three out of four conversions were correct.

Next thing I tried was to play with the precision setting of php. After changing the value to '13' the conversion problem disappeared. But even after changing it back to the default setting the issue hasn't occurred anymore. 

I don't trust the situation. The bug probably still exists, but it's very hard to reproduce. We didn't have the bug while we used version 5.2.0, but it happened with 5.2.12 and 5.3.1.

----------------
Our system:

Windows Server 2003 R2, Standard Edition, Service Pack 2
Intel Core 2 CPU 6600 @ 2.40 GHz, 3,99 GB RAM
PHP Version 5.2.12
 [2010-06-14 10:37 UTC] xiaobo dot bob at gmail dot com
2010-06-14 09:30:45 BST

I have reproduced this bug, but after changed some setting: change the "precision" and "serialize_precision" setting in php.ini, and even changed back, or maybe after i added the printf("%.2f\n",$v2), the echo $v2 is correctted, but the printf result is always 16.:
 finally, i wrote such a script:

for ($i=0; $i<400; $i++)
{
echo $i."-";
printf("%f\n",$i);
}

and found there're 8 number have this bug, they are:
17
19
29
39
170
190
290
390

I'm using windows xp in a virtualbox virtual machine, and a delphi component named php4delphi, the php version is 5.2.13
 [2010-06-14 10:39 UTC] pajoye@php.net
-Status: Assigned +Status: Feedback
 [2010-06-14 10:39 UTC] pajoye@php.net
xiaobo dot bob at gmail dot com:

Which setting do you use for  "precision" and "serialize_precision"?
 [2010-06-14 12:48 UTC] xiaobo dot bob at gmail dot com
i just changed the number several time, larger or zero, but i don't know which takes the effects.

i think the problem is in the function "number_format".
now in my envirentment, 
"echo number_format(17.0,0)" is correct, result: 17
"echo number_format(17.0,1)" is wrong, result: 16.:
"echo number_format(17.0,3)" is wrong, result: 16.:00
 [2010-06-14 12:53 UTC] pajoye@php.net
Which settings were used when you get these results? simply use ini_set to fetch them.
 [2010-06-14 12:54 UTC] xiaobo dot bob at gmail dot com
wrong result for the following number is like:
17 - 16.:00
19 - 18.:00
29 - 28.:00
39 - 38.:00
170 - 16:.00
190 - 18:.00
290 - 28:.00
390 - 38:.00
1700 - 1,6:0.00
1900 - 1,8:0.00
 [2010-06-14 14:29 UTC] xiaobo dot bob at gmail dot com
i tried set precision to 5/14/20, and keep the serialize_precision = 100.

"echo number_format(1900.0,2)" is always wrong.

here is my code:

echo ini_get("precision")."/".ini_get("serialize_precision")."<br>";
echo number_format(1900.0,2)."-------\n";
 [2010-06-15 03:49 UTC] xiaobo dot bob at gmail dot com
I have a win32 program writing in delphi using the component php4delphi that can reproduce this problem. if someone need it, i can email it to you.

or if some one can help me to compile php under vc6 with the .dsp (I can compile 5.3.2 using nmake of vc++9, with the step-by-step direction of the manual, but failed to compile using .dsp project). i have tried to use the windbg.exe with the downloaded debug pack to trace into the code, it seems the problem happens in the function php_conv_fp in snprintf.c, but as the local variables always "memory access error", i can't make any progress.
 [2010-07-12 12:43 UTC] ola dot andersson at liko dot se
The same error occurred for me. The installation is PHP 5.2.13 installed on IIS7/Win server 2008.

Writing a script as suggested (see below) produces incorrect output for the echo function. The error is however intermittent. 

When refreshing the browser and rerunning the script several times (perhaps 20-40 times) the correct numbers are sometimes displayed and sometimes the incorrect.

Script used for testing:

for ($i=0; $i<400; $i++)
{
echo $i."-";
printf("%f\n",$i);
}
 [2010-07-12 12:53 UTC] ola dot andersson at liko dot se
Error occur also when fetching data from a MS SQL server having the column value 290.00 (database Money format). 

$query ="select pris from sa_jobb_3_1 WHERE id='".$id."'";
$result = mssql_query($query) or die($query);
$row = mssql_fetch_array($result,MSSQL_ASSOC);
printf("%f",$row['pris']);			

The code above outputs incorrectly 28:.000000 and not as expected 290.000000
 [2010-07-12 13:48 UTC] pajoye@php.net
Please try with 5.3.2 or 5.3.3RC2 VC9 version.
 [2010-07-13 12:45 UTC] ola dot andersson at liko dot se
Thank you for your suggestion pajoye.

Neither php-5.3.2-nts-Win32-VC6-x86 or php-5.3.2-nts-Win32-VC9-x86 include the extension php_mssql.dll. Without this extension I am not able to properly upgrade and test our systems with this version of PHP. 

Howcome php_mssql is no longer included with the distributions?
 [2010-11-08 18:54 UTC] lennart dot vandendool at fonq dot nl
-: lennartvdd@mailordersolutions.nl +: lennart dot vandendool at fonq dot nl -Status: Feedback +Status: Assigned
 [2010-11-08 18:54 UTC] lennart dot vandendool at fonq dot nl
I just tested php-5.3.3-Win32-VC9-x86 on Windows Server 2003 x86 and 2008 R2 x64. The problem doesn't occur anymore.
 [2010-11-08 19:04 UTC] lennart dot vandendool at fonq dot nl
The same goes for php-5.3.3-nts-Win32-VC9-x86 on SBS 2003 (x86) and 2008 R2 (x64)
 [2011-09-12 13:29 UTC] michael dot fellinger at multitec-sono dot at
Similar Bug in PHP Version 5.3.5

My Code:
----------------------------------------------
$ADODB = new COM( 'ADODB.Connection' );
$ADODB->open($strConn);

$RS = $ADODB->execute("SELECT Lagerwert FROM tblStammdaten WHERE tblStammdaten.Seriennummer='74925KR9';");
echo $RS->Fields(0)->Value . "<br>";
$x = sprintf("%f",$RS->Fields(0)->Value);
echo $x;
----------------------------------------------
gives following result:
-----------------------
1900
18:0.000000 
-----------------------------------------------
It only happends with the number or string 1900 and only if the execute command from the adodb connection was performed.
I gues i also happens with other numbers.
 [2013-01-08 07:29 UTC] pajoye@php.net
-Status: Assigned +Status: Wont fix
 [2013-01-08 07:29 UTC] pajoye@php.net
Happens only on some 2003/xp, system APIs bugs or locale error, we can't fix it. 
Also XP/2003 series won't be supported anymore in 5.5 or later, mark as 'won't 
fix'.
 
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Tue Jan 26 08:01:29 2021 UTC