php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #47716 Invalid/Corrupt Math Convert string to float
Submitted: 2009-03-19 12:11 UTC Modified: 2009-04-22 17:22 UTC
From: codeslinger at compsalot dot com Assigned:
Status: Not a bug Package: Scripting Engine problem
PHP Version: 5.2.9 OS: windows 2000
Private report: No CVE-ID: None
 [2009-03-19 12:11 UTC] codeslinger at compsalot dot com
Description:
------------
It is with great hesitancy that I enter this bug, because I am not able to produce a simple test case for it.  But the bug is very serious.

I have a program that calculates and sends out customer statements.  

Without making any changes to the php program itself which has been running fine, I upgraded to PHP 5.2.9  and also tested with 5.2.9-1  both with and without xdebug enabled.

The math is bad, the calculations are incorrect.  Below is a program that displays this problem, but it does not fail when run stand-alone, this program only fails when run inside of the billing program's context where it is calculating the statement balances.

The billing program of course does a billion things before it gets to this point.  But at that point the math behavior of PHP is corrupt.  Wrong math results are the only visible sign of the problem, the program runs to completion and prints the statements etc.

The program reads the numbers from a database as strings and converts them to floats to do the totals.  This is not a case of loss of precision, as I said the program runs fine on 5.2.5.   But sprintf will convert "19.000000" to = 18:0

Note the colon, I'm using the default language settings of USA English.

Probably related to Bug #47304


Reproduce code:
---------------
<?php
//I ran a series of tests all of them failed, 
//it was totally consistent and reproducible.  
//Here are the most interesting tests/results.

$arrMsgs = array();

//for the sake of completeness, I also added this, 
//it made no difference
$arrMsgs[] = "Locale = ".setlocale(LC_ALL, "english-usa");

$arrMsgs[] = "memory_get_peak_usage(true) = ". memory_get_peak_usage(true);
$arrMsgs[] = "memory_get_peak_usage(false) = ". memory_get_peak_usage(false);
$arrMsgs[] = "memory_get_usage(true) = ". memory_get_usage(true);
$arrMsgs[] = "memory_get_usage(false) = ". memory_get_usage(false);


$arrMsgs[] = "(float)19.000000 = ".(float)19.000000;
$arrMsgs[] = "(float)'19.000000' = ".(float)'19.000000';
$arrMsgs[] = "round('19.000000', 2) = ".round('19.000000', 2);


print_r($arrMsgs);

?>


Expected result:
----------------
when I run this program on PHP 5.2.5  I get the following result


    [DebugInfo] => Array
        (
            [0] => memory_get_peak_usage(true) = 3932160
            [1] => memory_get_peak_usage(false) = 3731872
            [2] => memory_get_usage(true) = 3932160
            [3] => memory_get_usage(false) = 3589320

            [10] => (float)19.000000 = 19
            [11] => (float)'19.000000' = 19
            [12] => round('19.000000', 2) = 19

        )


Actual result:
--------------
    [DebugInfo] => Array
        (
            [0] => memory_get_peak_usage(true) = 3932160
            [1] => memory_get_peak_usage(false) = 3732128
            [2] => memory_get_usage(true) = 3932160
            [3] => memory_get_usage(false) = 3589216

            [10] => (float)19.000000 = 18.:
            [11] => (float)'19.000000' = 18.:
            [12] => round('19.000000', 2) = 18.:
        )


notice the colons following the numbers, I did not add those, it is part of the failure.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-03-20 15:40 UTC] codeslinger at compsalot dot com
in case it wasn't clear from the description above, this is using the CLI version of php.

also unlike a number of other bugs that I have read.  Adding and removing various lines of code -- which I did quite a bit of while isolating this problem, plus adding a planned revision to the code -- had no effect on the result, the bug was totally repeatable.  

This was using the official php windows binary, not one that I compiled.  The only difference between the working and not working versions of the program are the php version.

How is it possible to convert a string to a float and have the result contain a colon character???
 [2009-03-20 15:57 UTC] pajoye@php.net
I'm not sure what's wrong.

Here is what I get:

Windows 2008 (latest SP):
Array
(
    [0] => Locale = English_United States.1252
    [1] => memory_get_peak_usage(true) = 262144
    [2] => memory_get_peak_usage(false) = 58240
    [3] => memory_get_usage(true) = 262144
    [4] => memory_get_usage(false) = 57240
    [5] => (float)19.000000 = 19
    [6] => (float)'19.000000' = 19
    [7] => round('19.000000', 2) = 19
)

Windows 2003 (latest SP):
Array
(
    [0] => Locale = English_United States.1252
    [1] => memory_get_peak_usage(true) = 262144
    [2] => memory_get_peak_usage(false) = 56152
    [3] => memory_get_usage(true) = 262144
    [4] => memory_get_usage(false) = 56024
    [5] => (float)19.000000 = 19
    [6] => (float)'19.000000' = 19
    [7] => round('19.000000', 2) = 19
)


Windows XP sp2:
Array
(
    [0] => Locale = English_United States.1252
    [1] => memory_get_peak_usage(true) = 262144
    [2] => memory_get_peak_usage(false) = 57112
    [3] => memory_get_usage(true) = 262144
    [4] => memory_get_usage(false) = 56112
    [5] => (float)19.000000 = 19
    [6] => (float)'19.000000' = 19
    [7] => round('19.000000', 2) = 19
)


 [2009-03-20 16:04 UTC] pajoye@php.net
Please reply in #47304 (duplicated).
 [2009-04-22 17:22 UTC] codeslinger at compsalot dot com
This is a copy of the comment that I put into Bug #47304  That bug has now been closed due to lack of activity.  So, we now have multiple closed bugs, no fixes in sight, no further dev activity expected, and a very serious problem remains.

-----------

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.

-----

P.S.  my program has some dependencies on PECL libs, it turns out not to be possible for me to run 5.3 at this time.
 [2010-05-13 21:28 UTC] derek dot ethier at humber dot ca
Cross-posting this with: http://bugs.php.net/bug.php?id=49764

It appears to happen randomly with either the number_format function or with converting str to float. The only consistent element is that the converted/formatted number contains a 9.

At least in my experience.
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Sun Dec 08 02:01:25 2019 UTC