PHP 格式化长数字时给出不正确的结果

PHP gives incorrect results when formatting long numbers

我正在为网站目的处理大量数据,我需要长时间的计算。当我回显一个长数字时,我没有得到正确的输出。

例子

// A random number
$x = 100000000000000000000000000;

$x = number_format($x);
echo "The number is: $x <br>";
// Result: 100,000,000,000,000,004,764,729,344 
// I'm not getting the value assigned to $x

您的数字实际上对于 php 个标准整数来说太大了。 php 使用 64 位整数,可以保存 -9223372036854775808 范围内的值 (PHP_INT_MIN) 至 +9223372036854775807 (PHP_INT_MAX).

您的数字大约有 87 位长,这实在是太多了。

如果你真的需要这么大的数字,你应该使用 php BC 数学类型,在手册中有解释:http://php.net/manual/en/ref.bc.php

如果你只是想格式化一个像一个巨大的数字一样的字符串,那么使用这样的东西:

function number_format_string($number) {
    return strrev(implode(',', str_split(strrev($number), 3)));
}

$x = '100000000000000000000000000';

$x = number_format_string($x);
echo "The number is: $x\n";

// Output: The number is: 100,000,000,000,000,000,000,000,000

编辑: 添加了 strrev() 函数,因为字符串在拆分之前需要反转(感谢@ceeee 的提示)。这样可以确保当输入的长度不能被 3 整除时,分隔符位于正确的位置。生成的字符串之后需要再次反转。

可以在 http://sandbox.onlinephpfunctions.com/code/c10fc9b9e2c65a27710fb6be3a0202ad492e3e9a

找到工作示例

64 位 PHP 安装中可以表示的最大整数,与您的数字相比:

   9,223,372,036,854,775,808 - largest possible signed 64bit integer
   100000000000000000000000000 - your number

由于您超出了最大数字大小,如果不使用 gmp/bcmath.

之类的东西,您将无法期望获得有用的结果

http://php.net/manual/en/function.number-format.php

这就是解决方案:

<?php

#    Output easy-to-read numbers
#    by james at bandit.co.nz
function bd_nice_number($n) {
    // first strip any formatting;
    $n = (0+str_replace(",","",$n));
    // is this a number?
    if(!is_numeric($n)) return false;
    // now filter it;
    if($n>1000000000000) return round(($n/1000000000000),1).' trillion';
    else if($n>1000000000) return round(($n/1000000000),1).' billion';
    else if($n>1000000) return round(($n/1000000),1).' million';
    else if($n>1000) return round(($n/1000),1).' thousand';

    return number_format($n);
    }
?>

回答@maxhb 有错误。如果输入为“10000000000000000000000”,则输出为:

The number is: 100,000,000,000,000,000,000,00

这是不正确的。所以试试下面的代码:

function number_format_string($number, $delimeter = ',')
{
    return strrev(implode($delimeter, str_split(strrev($number), 3)));
}

$x = '10000000000000000000000';

$x = number_format_string($x);
echo "The number is: $x\n";

// Output: The number is: 10,000,000,000,000,000,000,000

PHP 尚不支持格式化长数字,即使您始终将它们作为字符串保存在代码中(以避免 PHP 的 int 类型出现问题):

php > echo number_format('100000000000000000000000000');
100,000,000,000,000,004,764,729,344
php > echo number_format('3.14159265358979323846', 20);
3.14159265358979311600

底层 ICU 库支持格式化任意精度十进制数,但 PHP 尚未使用相关功能 – 参见 request #76093