Bug #68200 [Com]: json_decode rounding floats to 3 digits precision

From: Date: Fri, 07 Nov 2014 09:09:17 +0000
Subject: Bug #68200 [Com]: json_decode rounding floats to 3 digits precision
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-188501@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=68200&edit=1

 ID:                 68200
 Comment by:         admin at bittylicious dot com
 Reported by:        vwirus at o2 dot pl
 Summary:            json_decode rounding floats to 3 digits precision
 Status:             Not a bug
 Type:               Bug
 Package:            JSON related
 Operating System:   linux/debian
 PHP Version:        5.5.17
 Block user comment: N
 Private report:     N

 New Comment:

I absolutely second vwirus's suggestion that we add a new options flag for json_decode to also
treat floats as strings.

My workaround for now, which is definitely a kludge, is to preg_replace all numbers, including
floats, with quotes. This keeps things as a string and thus doesn't lose any precision.

Perhaps this can be converted to a feature request?


Previous Comments:
------------------------------------------------------------------------
[2014-10-13 10:26:45] vwirus at o2 dot pl

You not always able to call ini_set, and i high load apps you shouldn't.
Also let's say you dealing with numbers up to 18 significant digits.
So you're setting:
ini_set('precision', 18);

but:

$tmp = json_decode('{"number": 1000000.66599998}', true);
var_dump($tmp);

displays:
array(1) {
  ["number"]=>
  float(1000000.66599997994)
}

So important information is lost!

------------------------------------------------------------------------
[2014-10-10 18:43:03] requinix@php.net

> But it's not very stright forward and not possible in  shared hosting.
All you need to add is
  ini_set("precision", 15);

------------------------------------------------------------------------
[2014-10-10 09:20:00] vwirus at o2 dot pl

Thank you that solved my problem. But it's not very stright forward and not possible in  shared
hosting. A s json is "transport" layer for most php apps I think there should be flag in
json_decode similar to JSON_BIGINT_AS_STRING f.e. JSON_FLOAT_AS_STRING that converts floats to
stings and avoid rounding and losing precision. Such string could be easy used with BC_MATH

------------------------------------------------------------------------
[2014-10-09 17:36:44] requinix@php.net

14 digits of precision goes all the way to
  1000000.66599998
                ^
so yes, it will round to .666. By the way, "significant digits" are not just the decimal
places so it rounded to 10 digits, not 3.

Push your precision up to 15 or more and it will save as you want.

------------------------------------------------------------------------
[2014-10-09 14:22:21] marcin at urzenia dot net

It's float problem, not JSON:

var_dump((float)"1000000.66599998") => float(1000000.666)

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


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

    https://bugs.php.net/bug.php?id=68200


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


Thread (8 messages)

« previous php.bugs (#188501) next »