Bug #50224 [Com]: json_encode() does not always encode a float as a float

From: Date: Sat, 29 Mar 2014 23:52:27 +0000
Subject: Bug #50224 [Com]: json_encode() does not always encode a float as a float
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-184962@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=50224&edit=1

 ID:                 50224
 Comment by:         jrbasso 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.5.10.

I opened a PR to resolve it. https://github.com/php/php-src/pull/635


Previous Comments:
------------------------------------------------------------------------
[2013-07-03 13:42:20] chr dot tatu at gmail dot com

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.

------------------------------------------------------------------------
[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] jani@php.net

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.

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


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


Thread (13 messages)

« previous php.bugs (#184962) next »