计算非常大的数字的 a % b - php

3
我需要计算两个非常大的数字 ab 的模(余数)a % b。由于它们超过了 PHP_INT_MAX,因此我无法使用默认的模运算符,而必须将它们视为 "字符串" 处理。
虽然有一些特殊的数学库,如 BCGMP,但我不能使用它们,因为我的应用程序可能会托管在共享主机上,这些库未被启用。因此,我需要编写一个 PHP 函数来完成这项工作。该函数将接受两个字符串参数(即两个数字),并返回 a % b 的值。但我不知道从哪里开始?如何解决这个问题?
4个回答

3
自PHP 4.0.4版本起,libbcmath已经内置于PHP中,您不需要任何外部库来启用此扩展。这些函数仅在PHP配置时使用--enable-bcmath可用。
Windows版本的PHP已经内置了对此扩展的支持,您无需加载任何额外的扩展即可使用这些函数。您应该能够自己启用这些函数,而不需要主机公司采取任何措施。

您可以查看此脚本输出的配置部分,以查看是否存在bcmath(它始终存在!)。<?php phpinfo(); - Ray Paseur
1
如果您在注释中使用反引号来标记代码,它将被正确格式化... <?php phpinfo(); ?> - Basic
你是对的,我有一个gmp的问题,但我可以使用bc。感谢您反映这一点。 - Tamás Pap

2
我想到了这个解决方案: $n代表一个巨大的数字,$m代表(不那么巨大的)模数。
function getModulus($n, $m)
{
    $a = str_split($n);
    $r = 0;

    foreach($a as $v)
    {
        $r = ((($r * 10) + intval($v)) % $m);
    }

    return $r;
}

希望这能帮助到某些人,

1

根据您的处理器,如果使用64位机器,则2^63-1;如果使用32位机器,则2^31-1应该给出您的机器可以计算的十进制长度。超过这个长度,您将得到错误的值。 您可以通过将数字拆分成块来执行相同的操作。 例如:我的数字有18位小数,因此拆分成9/7/2 = 18个块。 计算第一个块的模数。 将第一个的模数添加到第二个块的前面。 例如:第一个模数的结果为23,因此为23XXXXXXX。找到结果23XXXXXXX的模数。将模数添加到最后一个块中。例如:模数=15,那么为15XX。

$string = '123456789123456789'; // 18 decimal long
$chunk[0] = '123456789'; // 9 decimal long
$chunk[1] = '1234567'; // 7 decimal long
$chunk[2] = '89'; // 2 decimal long
$modulus = null;
foreach($chunk as $value){
$modulus = (int)($modulus.$value) % 45;
}

上面的 $modulus 结果应与以下结果相同

$modulus = $tring % 45 宁愿晚一点,也不要出错。 希望这能帮到你。有没有使用类似方法的人?


0

2
使用如此大的数字时,你会得到相当显著的舍入误差。 - Basic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接