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] j...@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.

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

[2009-11-19 08:51:56] j...@php.net

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