Gwi*_*d31 67 php precision json php-7.1
这不是一个问题,因为它更多的是意识到.我更新了一个json_encode()用于PHP7.1.1 的应用程序,我看到一个问题,浮动被更改为有时延伸出17位数.根据文档,serialize_precision在编码double值时,PHP 7.1.x开始使用而不是精度.我猜这导致了一个示例值
472.185
成为
472.18500000000006
在那个价值经历之后json_encode().自从我发现以来,我已经恢复到PHP 7.0.16并且我不再有问题了json_encode().我还尝试在恢复到PHP 7.0.16之前更新到PHP 7.1.2.
这个问题背后的原因确实源于PHP - 浮点数精度,但最终所有原因都是因为从精度到serialize_precision使用的变化json_encode().
如果有人知道这个问题的解决方案,我会非常乐意听取推理/修复.
摘自多维数组(之前):
[staticYaxisInfo] => Array
(
[17] => stdClass Object
(
[variable_id] => 17
[static] => 1
[min] => 0
[max] => 472.185
[locked_static] => 1
)
)
Run Code Online (Sandbox Code Playgroud)
经过json_encode()......之后
"staticYaxisInfo":
{
"17":
{
"variable_id": "17",
"static": "1",
"min": 0,
"max": 472.18500000000006,
"locked_static": "1"
}
},
Run Code Online (Sandbox Code Playgroud)
Mac*_*ity 74
这驱使我坚果一点,直到我终于找到了这个bug指向你这个RFC其说
目前
json_encode()使用EG(精度)设置为14.这意味着最多14位用于显示(打印)该数字.IEEE 754 double支持更高的精度和serialize()/var_export()使用PG(serialize_precision),设置为17默认为更精确.由于json_encode()使用EG(精度),json_encode()即使PHP的浮点数可以保持更精确的浮点值,也可以删除小数部分的低位数并破坏原始值.
而且(强调我的)
这个RFC建议引入一个新设置EG(precision)= - 1和PG(serialize_precision)= - 1,它使用zend_dtoa()的模式0,它使用更好的算法来舍入浮点数(-1用于表示0模式).
简而言之,有一种新方法可以使PHP 7.1 json_encode使用新的和改进的精确引擎.在php.ini中,您需要更改serialize_precision为
serialize_precision = -1
Run Code Online (Sandbox Code Playgroud)
您可以使用此命令行验证它是否有效
php -r '$price = ["price" => round("45.99", 2)]; echo json_encode($price);'
Run Code Online (Sandbox Code Playgroud)
你应该得到
{"price":45.99}
Run Code Online (Sandbox Code Playgroud)
ale*_*lev 25
作为一个插件开发人员,我没有对服务器的php.ini设置的一般访问权限.因此,根据Machavity的回答,我编写了一小段代码,您可以在PHP脚本中使用它.只需将其放在脚本之上,json_encode就会像往常一样继续工作.
if (version_compare(phpversion(), '7.1', '>=')) {
ini_set( 'serialize_precision', -1 );
}
Run Code Online (Sandbox Code Playgroud)
小智 12
我通过将 precision 和 serialize_precision 设置为相同的值(10)解决了这个问题:
ini_set('precision', 10);
ini_set('serialize_precision', 10);
Run Code Online (Sandbox Code Playgroud)
您也可以在 php.ini 中进行设置
我正在对货币值进行编码,并且将330.46编码到330.4600000000000363797880709171295166015625. 如果您不想或不能更改 PHP 设置并且您事先知道数据的结构,那么有一个非常简单的解决方案对我有用。只需将其强制转换为字符串(以下两者都做同样的事情):
$data['discount'] = (string) $data['discount'];
$data['discount'] = '' . $data['discount'];
Run Code Online (Sandbox Code Playgroud)
对于我的用例,这是一个快速有效的解决方案。请注意,这意味着当您将其从 JSON 解码回来时,它将是一个字符串,因为它将用双引号括起来。