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 andserialize()
/var_export()
uses PG(serialize_precision) which set to 17 be default to be more precise. Sincejson_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 andserialize()
/var_export()
uses PG(serialize_precision) which set to 17 be default to be more precise. Sincejson_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
How to Call a Closure That Is a Class Variable
How to Get Client Ip Address in Laravel 5+
Beautiful Way to Remove Get-Variables with PHP
How to Include PHP Files That Require an Absolute Path
Run a MySQL Query as a Cron Job
PHP Exec() as Background Process (Windows Wampserver Environment)
Generate Seo Friendly Urls (Slugs)
Dynamic Class Method Invocation in PHP
Passing a Variable from One PHP Include File to Another: Global VS. Not
The Post Method Is Not Supported for This Route. Supported Methods: Get, Head. Laravel
Trying to Access Array Offset on Value of Type Bool in PHP 7.4
Type Hinting - Specify an Array of Objects
Strip All HTML Tags, Except Allowed
PHP Remove Special Character from String
Php: Using a Variable Inside a Double Quotes
How to Get Rid of MySQL Error 'Prepared Statement Needs to Be Re-Prepared'