PHP7.1 json_encode()浮动问题 [英] PHP7.1 json_encode() Float Issue
问题描述
这不是一个问题,因为更多的是要意识到.我将使用json_encode()
的应用程序更新为PHP7.1.1,并且看到浮点数被更改为有时扩展为17位的问题.根据文档,在对双精度值进行编码时,PHP 7.1.x开始使用serialize_precision
而不是精度.我猜这导致了
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
472.185
成为
472.18500000000006
472.18500000000006
该值经过json_encode()
之后的
.自发现以来,我已恢复为PHP 7.0.16,并且不再遇到json_encode()
的问题.在还原到PHP 7.0.16之前,我还尝试过更新到PHP 7.1.2.
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.
该问题背后的原因确实来自 PHP-浮点数精度,但是最后造成这种情况的所有原因是因为json_encode()
中的精度用法从精度更改为serialize_precision.
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
)
)
并经过json_encode()
...
"staticYaxisInfo":
{
"17":
{
"variable_id": "17",
"static": "1",
"min": 0,
"max": 472.18500000000006,
"locked_static": "1"
}
},
推荐答案
这使我有点发疯,直到我终于找到此RFC 其中说
This drove me nuts for a bit until I finally found this bug which points you to this RFC which says
当前
json_encode()
使用设置为14的EG(精度).这意味着最多使用14位数字来显示(打印)该数字. IEEE 754 double支持更高的精度,并且serialize()
/var_export()
使用PG(serialize_precision),将其设置为默认值17更为精确.由于json_encode()
使用EG(precision),因此即使PHP的float可以容纳更精确的float值,json_encode()
也会删除小数部分的小数并破坏原始值.
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.
然后(强调我的意思)
此RFC建议引入一个新设置EG(precision)=-1和 PG(serialize_precision)=-1,该设置使用zend_dtoa()的模式0,该模式使用更好的算法对舍入浮点数(-1为表示0模式).
简而言之,有一种使PHP 7.1 json_encode
使用新的和改进的精度引擎的新方法.在 php.ini 中,您需要将serialize_precision
更改为
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);'
您应该获得
{"price":45.99}
这篇关于PHP7.1 json_encode()浮动问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!