58

要像在对大数(100,000+)使用费马素性检验时所需的那样使用模幂运算,它需要一些非常大的计算。

当我将两个大数(例如:62574 和 62574)相乘时,PHP 似乎将结果转换为浮点数。获取它的模值会返回奇怪的值。

$x = 62574 * 62574;
var_dump($x);          // float(3915505476) ... correct
var_dump($x % 104659); // int(-72945)  ... wtf.

有没有办法让 PHP 正确执行这些计算?或者,是否有另一种方法可以找到适用于大数的模值?

4

8 回答 8

55

出于某种原因,PHP 中有两个标准库可以处理任意长度/精度的数字:BC MathGMP。我个人更喜欢 GMP,因为它更新鲜,API 更丰富。

基于 GMP,我实现了 Decimal2 类来存储和处理货币金额(如 100.25 美元)。有很多mod 计算没有任何问题。用非常大的数字进行测试。

于 2008-10-17T09:35:02.843 回答
50

用这个

 $num1 = "123456789012345678901234567890";
 $num2 = "9876543210";
 $r    = mysql_query("Select @sum:=$num1 + $num2");
 $sumR = mysql_fetch_row($r);
 $sum  = $sumR[0];
于 2011-05-17T06:23:17.837 回答
21

你看过bcmod()吗?php 在 32 位平台上存在整数超过 2^31 - 1 的问题。

var_dump(bcmod("$x", '104659') ); // string(4) "2968"
于 2008-10-17T08:10:16.057 回答
4

我建议你试试BigInteger。如果这不起作用,您可以使用SWIG为大整数计算添加 C/C++ 代码并将其链接到您的代码中。

于 2008-10-17T08:08:04.627 回答
3

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:

/**
 * @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"
于 2014-02-02T10:08:44.260 回答
3

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.

You may check some good GMP functions in the official PHP manual here- http://php.net/manual/en/ref.gmp.php

于 2015-05-17T11:57:35.543 回答
2
$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);
于 2012-09-15T08:04:06.093 回答
2
<?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);
?>
于 2019-09-22T14:58:53.623 回答