格式化长数字时PHP会给出错误的结果

时间:2016-02-03 06:26:04

标签: php integer number-formatting biginteger arbitrary-precision

我正在处理大量网站用途,我需要长时间的计算。当我回复一个很长的数字时,我得不到正确的输出。

示例

// 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

5 个答案:

答案 0 :(得分:9)

对于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

找到工作示例

答案 1 :(得分:6)

回答@maxhb有bug。如果输入是&#39; 10000000000000000000000&#39;输出将是:

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

答案 2 :(得分:2)

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

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

由于您超过了最大数量,因此如果不使用gmp / bcmath之类的内容,您就无法获得有用的结果。

答案 3 :(得分:0)

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

答案 4 :(得分:-1)

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