在PHP中使用大数字
要使用大量(100,000+)以上的费马原始性测试时所需的模幂运算 ,需要进行一些非常大的计算。
当我乘以两个大数字(例如:62574和62574)PHP似乎将结果投入浮动。 获得它的模数值返回奇怪的值。
$x = 62574 * 62574; var_dump($x); // float(3915505476) ... correct var_dump($x % 104659); // int(-72945) ... wtf.
有什么办法让PHP正确执行这些计算吗? 另外,是否有另一种方法来寻找可用于大数目的模数值?
出于某种原因,PHP中有两个标准库处理任意长度/精度数字: BC Math和GMP 。 我个人更喜欢GMP,因为它更新鲜,API更丰富。
基于GMP,我实施了Decimal2类来存储和处理货币金额(如100.25美元)。 很多 mod计算没有任何问题。 测试的数量非常大。
用这个
$num1 = "123456789012345678901234567890"; $num2 = "9876543210"; $r = mysql_query("Select @sum:=$num1 + $num2"); $sumR = mysql_fetch_row($r); $sum = $sumR[0];
你看看bcmod()
吗? PHP在32位平台上的整数超过2 ^ 31 – 1。
var_dump(bcmod("$x", '104659') ); // string(4) "2968"
我建议你试试BigInteger 。 如果不能解决问题,可以使用SWIG为大整数计算添加C / C ++代码,并将其链接到代码中。
我发现另一个解决方案,但号码将被存储为一个字符串。 只要将其重新转换为数字,您将被限制在底层平台的精确度。 在一个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"
$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);
我为你写了一个非常小的代码,这个代码在大数字的情况下肯定会起作用,
<?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