ID:              50224
 User updated by: christian dot lawrence at calorieking dot com
 Reported By:     christian dot lawrence at calorieking dot com
 Status:          Bogus
 Bug Type:        JSON related
 PHP Version:     5.2SVN-2009-11-19 (snap)
 New Comment:

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.


Previous Comments:
------------------------------------------------------------------------

[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 http://bugs.php.net/?id=50224&edit=1

Reply via email to