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

答案@maxhb有错误。 如果输入是"10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

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

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

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

由于您超出了最大数字大小,因此如果不使用 gmp/bcmath 之类的东西,就不能指望获得有用的结果。

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 尚不使用相关函数 – 请参阅请求 #76093。

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);
    }
?>