Php素因子分解时间和大小问题

Php素因子分解时间和大小问题,php,python,int,prime-factoring,Php,Python,Int,Prime Factoring,有一个用于素因子分解的python实现代码。返回答案的时间大约为0.1秒。我为php实现了它。大量情况下,它运行约3秒(有时它从不返回答案) 注意:我甚至在php中使用函数来处理非常大的数字 注意:此函数(如下所述)中的所有其他函数都是单独测试的,但其中一个(pollard_brent)使用php内置函数gmp_mod。当我运行此命令时: // python handles these big numbers fine, and returns 1 for this: echo gmp_mod(

有一个用于素因子分解的
python
实现代码。返回答案的时间大约为
0.1
秒。我为
php
实现了它。大量情况下,它运行约3秒(有时它从不返回答案)

注意:我甚至在php中使用函数来处理非常大的数字

注意:此函数(如下所述)中的所有其他函数都是单独测试的,但其中一个(pollard_brent)使用php内置函数
gmp_mod
。当我运行此命令时:

// python handles these big numbers fine, and returns 1 for this:
echo gmp_mod(10000000000000000000001 , 2);
给我这个错误:

Message: gmp_mod(): Unable to convert variable to GMP - wrong type
我的因式分解代码:

public function primefactors($n, $sort = false) {
    $smallprimes = $this->primesbelow(10000);
    $factors = [];

    $limit = bcadd((bcpow($n, 0.5)) , 1);

    foreach ($smallprimes as $checker) {
        if ($checker > $limit) {
            break;
        }
        // while ($n%$checker == 0) {
        while ( bcmod($n, $checker) == 0 ) {
            array_push($factors, $checker);
            // $n = (int)($n/$checker);
            $n = bcdiv($n, $checker);
            // $limit = (int)(bcpow($n, 0.5)) + 1;
            // $limit = (bcpow($n, 0.5)) + 1;
            $limit = bcadd((bcpow($n, 0.5)) , 1);
            if ($checker > $limit) {
                break;
            }
        }
    }

    if ($n < 2) {
        return $factors;
    }

    while ($n > 1) {
        if ($this->isprime($n)) {
            array_push($factors, $n);
            // var_dump($factors);
            break;
        }
        $factor  = $this->pollard_brent($n);
        $factors = array_merge($factors, $this->primefactors($factor)); 
        $n = (int)($n/$factor);
    }
    if ($sort) {
        sort($factors);
    }

    return $factors;

}
公共函数primefactors($n,$sort=false){
$smallprimes=$this->primesbelow(10000);
$factors=[];
$limit=bcadd((bcpow($n,0.5)),1);
foreach($smallprimes作为$checker){
如果($checker>$limit){
打破
}
//而($n%$checker==0){
而(bcmod($n,$checker)==0){
数组_push($factors,$checker);
//$n=(int)($n/$checker);
$n=bcdiv($n,$checker);
//$limit=(int)(bcpow($n,0.5))+1;
//$limit=(bcpow($n,0.5))+1;
$limit=bcadd((bcpow($n,0.5)),1);
如果($checker>$limit){
打破
}
}
}
如果($n<2){
返回系数;
}
而($n>1){
如果($this->isprime($n)){
阵列推送($n);
//var_dump($因子);
打破
}
$factor=$this->pollard_brent($n);
$factors=array_merge($factors,$this->primefactors($factor));
$n=(int)($n/$factor);
}
如果($sort){
排序(系数);
}
返回系数;
}

有什么想法吗?

正如注释中所指出的,手册显示两个参数都必须是GMP对象或数字字符串。这样做:

echo gmp_mod("10000000000000000000001", "2");
较小的数字可能会起作用,因为PHP会在函数中将整数转换为字符串,但是
100000000000000000001
PHP\u INT\u MAX
长,因此它不起作用

echo 10000000000000000000001;
收益率:

1.0E+22

只是一个镜头,但根据的手册,这两个参数都应该是GMP对象,而不是数字…哎呀,我需要多读一读。说一个字符串就可以了。但我还是建议你尝试使用一个实例,看看是否有效。嗯,你甚至没有
GMP\u mod
code@JonathanKuhn但如果数量少,效果也不错。关于*我仍然建议尝试使用一个实例*你是什么意思?你需要完整的代码吗?看起来你正在向pollard_brent传递数组,这表明你正在向
gmp_mod
传递数组不,我不需要“完整的代码”。大多数GMP函数返回GMP对象的实例,而不是数字。您也可以使用GMP_init实例化GMP对象。我建议为您的数字创建一个GMP类实例,并将其传递到mod函数中。再加上这个,大的数字实际上将转换为指数
1.0E22
,这对于gmp函数是错误的。谢谢。但是有一个问题。这个非常大的数字是一个整数变量,所以当我使用这个:
gmp_mod((string)$var,“2”);
它给我错误:
无法将变量转换为gmp-string不是整数