在 PHP 中处理大数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/211345/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Working with large numbers in PHP
提问by nickf
To use modular exponentiationas you would require when using the Fermat Primality Testwith large numbers (100,000+), it calls for some very large calculations.
在使用大数 (100,000+)的费马素性检验时,要使用模幂运算,需要进行一些非常大的计算。
When I multiply two large numbers (eg: 62574 and 62574) PHP seems to cast the result to a float. Getting the modulus value of that returns strange values.
当我将两个大数(例如:62574 和 62574)相乘时,PHP 似乎将结果转换为浮点数。获取它的模值会返回奇怪的值。
$x = 62574 * 62574;
var_dump($x); // float(3915505476) ... correct
var_dump($x % 104659); // int(-72945) ... wtf.
Is there any way to make PHP perform these calculations properly? Alternatively, is there another method for finding modulus values that would work for large numbers?
有没有办法让 PHP 正确执行这些计算?或者,是否有另一种方法可以找到适用于大数的模数值?
采纳答案by Ivan Krechetov
For some reason, there are two standard libraries in PHP handling the arbitrary length/precision numbers: BC Mathand GMP. I personally prefer GMP, as it's fresher and has richer API.
出于某种原因,PHP 中有两个标准库处理任意长度/精度数:BC Math和GMP。我个人更喜欢 GMP,因为它更新鲜并且具有更丰富的 API。
Based on GMP I've implemented Decimal2 classfor storing and processing currency amounts (like USD 100.25). A lotof mod calculations there w/o any problems. Tested with verylarge numbers.
基于 GMP,我实施了Decimal2 类来存储和处理货币金额(如 100.25 美元)。那里有很多mod 计算,没有任何问题。用非常大的数字进行了测试。
回答by K.Sya
use this
用这个
$num1 = "123456789012345678901234567890";
$num2 = "9876543210";
$r = mysql_query("Select @sum:=$num1 + $num2");
$sumR = mysql_fetch_row($r);
$sum = $sumR[0];
回答by Owen
回答by Yuval F
I suggest you try BigInteger. If that doesn't work out, you may use SWIGto add C/C++ code for the big integer calculations and link it into your code.
我建议你试试BigInteger。如果这不起作用,您可以使用SWIG为大整数计算添加 C/C++ 代码并将其链接到您的代码中。
回答by Yuval F
I found another solution, but the number will be stored as a string. As soon as you cast it back to a numeric, you'll be restricted to the precision of the underlying platform. On a 32 bit platform, the largest int you can represent as an int type is 2,147,483,647:
我找到了另一个解决方案,但数字将存储为字符串。一旦您将其转换回数字,您将受到底层平台精度的限制。在 32 位平台上,可以表示为 int 类型的最大 int 是 2,147,483,647:
/**
* @param string $a
* @param string $b
* @return string
*/
function terminal_add($a, $b){
return shell_exec('echo "'.$a.'+'.$b.'"|bc');
}
// terminal_add("123456789012345678901234567890", "9876543210")
// output: "123456789012345678911111111100"
回答by gauravparmar
I wrote a very small code for you that will surely work in case of big numbers-
我为您编写了一个非常小的代码,在大数字的情况下肯定会起作用-
<?php
$x = gmp_strval(gmp_mul("62574","62574")); // $x="3915505476"
$mod=gmp_strval(gmp_mod($x,"104659")); //$mod="2968"
echo "x : ".$x."<br>";
echo "mod : ".$mod;
/* Output:
x : 3915505476
mod : 2968
*/
?>
You simply have to use strings for storing big numbers and to operate on them use GMP functions in PHP.
您只需要使用字符串来存储大数字,并使用 PHP 中的 GMP 函数对它们进行操作。
You may check some good GMP functions in the official PHP manual here- http://php.net/manual/en/ref.gmp.php
您可以在此处的官方 PHP 手册中查看一些不错的 GMP 功能 - http://php.net/manual/en/ref.gmp.php
回答by bob
$x = 62574 * 62574;
// Cast to an integer
$asInt = intval($x);
var_dump($asInt);
var_dump($asInt % 104659);
// Use use sprintf to convert to integer (%d), which will casts to string
$asIntStr = sprintf('%d', $x);
var_dump($asIntStr);
var_dump($asIntStr % 104659);
回答by Mrigank Shekhar
<?php
function add($int1,$int2){
$int1 = str_pad($int1, strlen($int2), '0', STR_PAD_LEFT);
$int2 = str_pad($int2, strlen($int1), '0', STR_PAD_LEFT);
$carry = 0;
$str = "";
for($i=strlen($int1);$i>0;$i--){
$var = $int1[$i-1] + $int2[$i-1] + $carry;
$var = str_pad($var, 2, '0', STR_PAD_LEFT);
$var = (string) $var;
$carry = $var[0];
$str = $str . $var[1];
}
$res = strrev($str.$carry);
echo ltrim($res,"0");
}
add($int1,$int2);
?>

