Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP: How to encode infinity or NaN numbers to JSON?

Apparently, infinity and NaN are not a part of JSON specification, so this PHP code:

$numbers = array();
$numbers ['positive_infinity'] = +INF;
$numbers ['negative_infinity'] = -INF;
$numbers ['not_a_number'] = NAN;
$array_print = print_r ($numbers, true);
$array_json = json_encode ($numbers);
echo "\nprint_r(): $array_print";
echo "\njson_encode(): $array_json";

Produces this:

PHP Warning:  json_encode(): double INF does not conform to the JSON spec, encoded as 0 in /home/septi/test.php on line 8
PHP Warning:  json_encode(): double -INF does not conform to the JSON spec, encoded as 0 in /home/septi/test.php on line 8
PHP Warning:  json_encode(): double NAN does not conform to the JSON spec, encoded as 0 in /home/septi/test.php on line 8

print_r(): Array
(
    [positive_infinity] => INF
    [negative_infinity] => -INF
    [not_a_number] => NAN
)

json_encode(): {"positive_infinity":0,"negative_infinity":0,"not_a_number":0}

Is there any way to correctly encode these numbers without writing my own json_encode() function? Maybe some workaround?

like image 348
Septagram Avatar asked Nov 27 '12 10:11

Septagram


2 Answers

You are right about the JSON spec:

Numeric values that cannot be represented as sequences of digits (such as Infinity and NaN) are not permitted.

The solution must also come from the spec, since a custom "JSON" encoder would not produce valid JSON anyway (you would have to write a custom decoder as well, and then you and consumers of your data would be forced to use that until the end of time).

Here' what the spec allows for values:

A JSON value MUST be an object, array, number, or string, or one of the following three literal names:

false null true

So, any workaround that involves legal JSON instead of a custom JSON-like protocol would involve using something else instead of numbers.

One reasonable option would be to use the strings "Infinity" and "NaN" for these edge cases.

like image 143
Jon Avatar answered Oct 26 '22 21:10

Jon


According to JSON spec, there is no Infinity or NaN values: http://json.org/

Workarounds:

  1. Reject using JSON (pure JSON), and write your own json_encode function, which will handle INF/NAN (converting to "Infinity" and "NaN" respectively), and make sure you are parsing JSON using something like result = eval('(' + json + ')'); on the client side.

  2. Pre convert your IFN/NAN values into string values ('Infinity' and 'NaN'), and when you are going to operate with those values in JavaScript, use the following construction: var number1 = (+numbers.positive_infinity);. This will convert string value 'Infinity' into numeric Infinity representation.

like image 32
mdevils Avatar answered Oct 26 '22 23:10

mdevils