Php7.1 JSON_Encode() Float Issue

PHP7.1 json_encode() Float Issue

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}

json_encode() float precision in PHP7 and addition operation

It seems like this is expected behavior (but not obvious IMO), according to the discussion here:
https://bugs.php.net/bug.php?id=75800

php json_encode display with number not correct from array

add this config

ini_set('serialize_precision', 14);
ini_set('precision', 14);

This is issue from php 7.1

PHP - float numbers wrong precision with json_decode

You can use number_format to remove the e-6 so you can store correctly in your database;

<?php

$inputJSON = '{"value":0.00000883}';
$outputJSON = json_decode($inputJSON);

$formatted = number_format($outputJSON->value,8);

print_r($formatted);

outputs: 0.00000883

Although, I'm pretty sure MySQL should handle 8.83E-6 as an input.

PHP7.1 json_encode() Float Issue

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}


Related Topics



Leave a reply



Submit