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


我正在为网站目的大量工作,我需要长时间的计算。当我回显一个很长的数字时,我得不到正确的输出。

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

3966
2018-02-03 06:26


起源

因为它的方式远远大于 PHP_INT_MAX 值。确切的数字是 2147483647 (32-bit) 和 9223372036854775807 (64-bit)。 php.net/manual/en/language.types.integer.php - Narendrasingh Sisodia
所以我应该用什么?如果它不支持或什么的 - deerox
这可能对你有帮助 stackoverflow.com/questions/19023840/... - Afsar
是的我知道int bigint,当然还有小数,但有没有解决方案? - deerox


答案:


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


9
2018-02-03 06:35



是的,我可以做一些事情,如将其转换为十进制? - deerox
添加了有关如何格式化字符串中包含的整数的示例。 - maxhb
谢谢让我尝试一下我更大的nubmers :) - deerox
有用的需要让我自己的功能更长的数字,但非常感谢它让我有一个想法:) - deerox
它真的是一个很好的例子,因为你不需要使用它 BC match PHP +1的类型 - Narendrasingh Sisodia


回答@maxhb有bug。如果输入为'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

5
2018-02-03 07:01



我的解决方案没有输出你说的内容,它输出我写的内容,请参阅 sandbox.onlinephpfunctions.com/code/... - maxhb
@maxhb嗨先生,试试10000000000000000000000 - Ceeee
除非我们给予,否则工作正常 $x = 100000000000000000000000000; - deerox
或尝试$ x = 1000.输出将是:数字是:100,0 - Ceeee


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

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

因为你超过了最大数量大小,所以如果不使用类似的东西,就不能指望获得有用的结果 GMP/bcmath时


2
2018-02-03 06:42





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

-1
2018-02-03 06:51



不,我不是在寻找用数十亿或数万亿来改变我的长数 - deerox