Edit report at https://bugs.php.net/bug.php?id=50224&edit=1
ID: 50224
Comment by: chr dot tatu at gmail dot com
Reported by: christian dot lawrence at calorieking dot com
Summary: json_encode() does not always encode a float as a
float
Status: Not a bug
Type: Bug
Package: JSON related
PHP Version: 5.2SVN-2009-11-19 (snap)
Block user comment: N
Private report: N
New Comment:
The problem is still present in version 5.4.6.
var_dump says this values is float, but after applying json_encode and
json_decode
the value gets to be an int.
For the jsoncpp library there is a difference between int and float and that
difference is acknowledged by the floating point.
Previous Comments:
------------------------------------------------------------------------
[2012-07-13 23:09:50] josh dot adell at gmail dot com
This is still an issue, specifically when JSON encoding for talking to APIs
that
don't allow mixed type arrays.
For instance, json_encode(array(1.2, 2.3)) properly encodes to "[1.2, 2.3]"
But, json_encode(array(1.0, 2.3)) encodes to "[1, 2.3]" which fails if the
receiving end does not allow mixed-type arrays.
Any chance on this ever being fixed?
PHP Version: 5.3.10
------------------------------------------------------------------------
[2009-11-20 10:39:53] christian dot lawrence at calorieking dot com
And there lines the problem - there is no way to express the fractional part if
json_encode() does not even deal with it in the first place.
An integer and an integer represented as a floating point number are not the
same thing because they have different types, as follows:
<?php
$a = 12;
var_dump($a); //int(12)
$b = 12.0; // This has a fractional part, hence it is a floating
point number and not an integer
var_dump($b); //float(12)
var_dump($a === $b); //bool(false)
?>
Numerically they have the same value, but we all know this to be true:
<?php
var_dump($a == $b); //bool(true)
?>
There is always a fractional part of any integer when it is represented as a
floating point number. It is implied and can, simply, be expressed by
appending a ".0" to the integer part. There is nothing in the JSON encoding
rules on http://www.json.org/ which disallows this (see "int frac" form for
specifics).
Decoding a valid and legitimate encoding of an integer when it is represented
as a floating point number gives the correct PHP floating point type:
<?php
var_dump(json_decode("12.0")); //float(12)
?>
Decoding an integer-encoded stream also gives the correct PHP integer type:
<?php
var_dump(json_decode("12")); //int(12)
?>
I fail to see how my bug report is bogus when json_encode() is unable to
produce a perfectly valid and legitimate encoding yet json_decode() is capable
of doing the right thing.
Surely, the json_encode() implementation must be identifying the data type
being encoded, presumably it is using equivalents for is_object() and
is_array(). Why not use equivalents for is_int() or is_float() as well?
A reliable data interchange format should not purport to do any type-casting
from the primitive types it was provided for encoding. ie: If you encode a
float then you should expect to decode a float. As far as I am concerned
json_encode() is un-reliable and fails to encode my float, which I have
confirmed in my results.
I humbly ask that you reconsider your position.
------------------------------------------------------------------------
[2009-11-19 15:12:56] [email protected]
Yes, IF you were passing fractional part. But you're not. See the output of
var_dump($f) in your results..
------------------------------------------------------------------------
[2009-11-19 09:14:05] christian dot lawrence at calorieking dot com
Take a look at the format for "number" at http://www.json.org/ and observe the
form for a "int frac". This clearly indicates that there is support for
representing a floating point number, even integer floats.
The json_encode() function clearly supports encoding of floating point numbers.
json_decode() is capable of deserialising "12.0" as a integer floating point
number.
If you encode a floating point number, then one should expect to decode a
floating point number.
If json_encode()/json_decode() is to be used as a serious and reliable data
exchange format, then there should be no loss or conversion of primitive type
information.
Please re-consider.
------------------------------------------------------------------------
[2009-11-19 08:51:56] [email protected]
There's is just "number" type in JSON for numbers. And as such, this is working
just like it should and PHP tries it's best at guessing what type the numbers
might be.
------------------------------------------------------------------------
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=50224
--
Edit this bug report at https://bugs.php.net/bug.php?id=50224&edit=1