PHP7.1 json_encode()浮动问题 [英] PHP7.1 json_encode() Float Issue

查看:174
本文介绍了PHP7.1 json_encode()浮动问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这不是一个问题,因为更多的是要意识到.我将使用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 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.

然后(强调我的意思)

此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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆