Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP7.1 json_encode() Float Issue

This isn't a question as it is more of a be aware. I updated an application that uses json_encode() to PHP7.1.1 and I was seeing an issue with floats being changed to sometimes extend out 17 digits. According to documentation, PHP 7.1.x started to use serialize_precision instead of precision when encoding double values. I'm guessing this caused an example value of

472.185

to become

472.18500000000006

after that value went through json_encode(). Since my discovery, I have reverted back to PHP 7.0.16 and I no longer have the issue with json_encode(). I also tried to update to PHP 7.1.2 before reverting back to PHP 7.0.16.

The reasoning behind this question does stem from PHP - Floating Number Precision, however the end all reason for this is because of the change from precision to serialize_precision usage in json_encode().

If anyone does know of a solution to this problem, I'd be more than happy to listen in on the reasoning/fix.

Excerpt from multidimensional array (before):

[staticYaxisInfo] => Array
                    (
                        [17] => stdClass Object
                            (
                                [variable_id] => 17
                                [static] => 1
                                [min] => 0
                                [max] => 472.185
                                [locked_static] => 1
                            )

                    )

and after going through json_encode()...

"staticYaxisInfo":
            {
                "17":
                {
                    "variable_id": "17",
                    "static": "1",
                    "min": 0,
                    "max": 472.18500000000006,
                    "locked_static": "1"
                }
            },
like image 955
Gwi7d31 Avatar asked Sep 30 '22 09:09

Gwi7d31


People also ask

What does the PHP function json_encode () do?

PHP | json_encode() Function The json_encode() function is an inbuilt function in PHP which is used to convert PHP array or object into JSON representation.

What is json_encode in JavaScript?

The PHP json_encode function translates the data passed to it to a JSON string which can then be output to a JavaScript variable. We demonstrate on this page with single level arrays. Other pages demonstrate using json_encode with multi-dimensional arrays and scalar values.

What is json_encode and Json_decode?

JSON data structures are very similar to PHP arrays. PHP has built-in functions to encode and decode JSON data. These functions are json_encode() and json_decode() , respectively. Both functions only works with UTF-8 encoded string data.

What is Json_numeric_check?

JSON_NUMERIC_CHECK (int) Encodes numeric strings as numbers. JSON_PRETTY_PRINT (int) Use whitespace in returned data to format it.


1 Answers

This drove me nuts for a bit until I finally found this bug which points you to this RFC which says

Currently json_encode() uses EG(precision) which is set to 14. That means that 14 digits at most are used for displaying (printing) the number. IEEE 754 double supports higher precision and serialize()/var_export() uses PG(serialize_precision) which set to 17 be default to be more precise. Since json_encode() uses EG(precision), json_encode() removes lower digits of fraction parts and destroys original value even if PHP's float could hold more precise float value.

And (emphasis mine)

This RFC proposes to introduce a new setting EG(precision)=-1 and PG(serialize_precision)=-1 that uses zend_dtoa()'s mode 0 which uses better algorigthm for rounding float numbers (-1 is used to indicate 0 mode).

In short, there's a new way to make PHP 7.1 json_encode use the new and improved precision engine. In php.ini you need to change serialize_precision to

serialize_precision = -1

You can verify it works with this command line

php -r '$price = ["price" => round("45.99", 2)]; echo json_encode($price);'

You should get

{"price":45.99}
like image 123
Machavity Avatar answered Oct 17 '22 15:10

Machavity