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

 ID:                 50224
 Comment by:         josh dot adell 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:

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


Previous Comments:
------------------------------------------------------------------------
[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.

------------------------------------------------------------------------
[2009-11-19 05:45:10] christian dot lawrence at calorieking dot com

Description:
------------
json_encode()-ing an integer when it is represented as floating point number 
results in a change of type when json_decode() decodes the output.

Examples of such floating point numbers are: -123.0, -1.0, 0.0, 1.0, 123.0

Reproduce code:
---------------
<?php

function jsonRoundTrip($f) {
        $e = json_encode($f);
        $d = json_decode($e);
        var_dump($f, $e, $d);
        echo "\n";
}

jsonRoundTrip(12.3);  // This is a float
jsonRoundTrip(12);  // This is an integer
jsonRoundTrip(12.0);  // This is an integer represented as a float
jsonRoundTrip(0.0);  // This is an integer represented as a float

?>


Expected result:
----------------
float(12.3)
string(4) "12.3"
float(12.3)

int(12)
string(2) "12"
int(12)

float(12)
string(4) "12.0"
float(12)

float(0)
string(3) "0.0"
float(0)


Actual result:
--------------
float(12.3)
string(4) "12.3"
float(12.3)

int(12)
string(2) "12"
int(12)

float(12)
string(2) "12"
int(12)

float(0)
string(1) "0"
int(0)



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



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

Reply via email to