58

フェルマーの素数性テストを多数(100,000以上)で使用する場合に必要となるようにべき乗剰余を使用するには、非常に大規模な計算が必要になります。

2つの大きな数(例:62574と62574)を乗算すると、PHPは結果をfloatにキャストするようです。そのモジュラス値を取得すると、奇妙な値が返されます。

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

PHPにこれらの計算を適切に実行させる方法はありますか?あるいは、大きな数で機能するモジュラス値を見つけるための別の方法はありますか?

4

8 に答える 8

55

何らかの理由で、任意の長さ/精度の数値を処理する PHP には 2 つの標準ライブラリがあります: BC MathGMPです。個人的には GMP の方が新鮮で API が充実しているので好みです。

GMP に基づいて、通貨金額 (USD 100.25 など) を格納および処理するためのDecimal2 クラスを実装しました。問題のない 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

大きな数の場合に確実に機能する非常に小さなコードを書きました-

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

大きな数値を格納するために文字列を使用し、それらを操作するには PHP の GMP 関数を使用するだけです。

ここの公式PHPマニュアルでいくつかの優れたGMP関数を確認できます- http://php.net/manual/en/ref.gmp.php

于 2015-05-17T11:57:35.543 に答える
3

別の解決策を見つけましたが、数値は文字列として保存されます。数値にキャストするとすぐに、基盤となるプラットフォームの精度に制限されます。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"
于 2014-02-02T10:08:44.260 に答える
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 に答える