为什么sprintf会改变打印数字的值?

时间:2017-02-25 08:44:28

标签: php

为什么以下代码

<?php
$x =965745973615421686;
print $x;
print '<br />';
print sprintf ( '%.0f', $x);

?>

打印错误的结果?

965745973615421686
965745973615421696

这是Windows 10 x64上的PHP7.1。 制作将是Ubuntu 16.04 32bit。

2 个答案:

答案 0 :(得分:2)

浮点运算很奇怪。 float是一堆有效数字后跟一个指数。问题是指数占用空间所以你只能(在64位系统中)只有53位,这是最大有效值9.0071993e + 15。在这种情况下,您似乎有2位数字,这意味着您拥有的数字,转换为float时将不具有100%的精度。

您需要通过执行

将其保留为int
print sprintf("%d",$x);

答案 1 :(得分:1)

您最有可能运行32位PHP,因此965745973615421686大于PHP_INT_MAX:

var_dump(PHP_INT_MAX, 965745973615421686);

在64位下打印:

int(9223372036854775807)
int(965745973615421686)

我目前没有32位PHP设置可供比较,但它会在此行上打印一些内容:

int(2147483647)
float(...)

此外,常规类型转换为字符串使用precision指令,因此小数位数可以变化,但在sprintf()中,您可以定义所需的完整小数:

ini_set('precision', 20);
var_dump((string)1.1, sprintf('%.1f', 1.1));
string(21) "1.1000000000000000888"
string(3) "1.1"