danaj / Math-Prime-Util-GMP

Perl prime number module using XS/GMP
Other
17 stars 9 forks source link

[optimization] is_semiprime() should check for perfect powers #24

Closed trizen closed 3 years ago

trizen commented 3 years ago

Currently, the is_semiprime function does not check for perfect powers. When given a square of a large prime, the functions takes a very time to determine that the number is indeed a semiprime.

use 5.014;
use Math::Prime::Util::GMP qw(is_semiprime powint is_prime_power);

my $n = powint("111111111111111111111113", 2);

say is_prime_power($n);      # 2
say is_semiprime($n);        # takes a very long time
trizen commented 3 years ago

Fixed in https://github.com/danaj/Math-Prime-Util-GMP/commit/a9dcd8e7be4133ccc94b0bc1a2b352d6ac9d6731. Thanks! :)

danaj commented 3 years ago

Thanks! Added to base code as well. E.g. before:

dana@hilbert:~/src/Math-Prime-Util$ make >/dev/null && time mpu '$s+=is_semiprime($_*$_) for 1..1e6; say $s'
78498

real    0m9.086s
user    0m9.062s
sys 0m0.020s

dana@hilbert:~/src/Math-Prime-Util$ make >/dev/null && time mpu '$s+=is_semiprime($_*$_*$_) for 1..1e6; say $s'
0

real    0m42.155s
user    0m41.979s
sys 0m0.078s

After:

dana@hilbert:~/src/Math-Prime-Util$ make >/dev/null && time mpu '$s+=is_semiprime($_*$_) for 1..1e6; say $s'
78498

real    0m0.595s
user    0m0.507s
sys 0m0.004s

dana@hilbert:~/src/Math-Prime-Util$ make >/dev/null && time mpu '$s+=is_semiprime($_*$_*$_) for 1..1e6; say $s'
0

real    0m1.310s
user    0m1.303s
sys 0m0.007s