mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-29 03:57:44 +00:00
factor::miller_rabin: Avoid unecessary exponentiation
Instead of computing a^r and a^(n-1) = a^(r 2ⁱ) separately, compute the latter by repeatedly squaring the former. 33.6% performance improvement
This commit is contained in:
parent
543c7b941a
commit
36a2948959
1 changed files with 19 additions and 6 deletions
|
@ -20,6 +20,7 @@ impl Result {
|
||||||
|
|
||||||
// Deterministic Miller-Rabin primality-checking algorithm, adapted to extract
|
// Deterministic Miller-Rabin primality-checking algorithm, adapted to extract
|
||||||
// (some) dividers; it will fail to factor strong pseudoprimes.
|
// (some) dividers; it will fail to factor strong pseudoprimes.
|
||||||
|
#[allow(clippy::many_single_char_names)]
|
||||||
pub(crate) fn test<A: Arithmetic>(n: u64) -> Result {
|
pub(crate) fn test<A: Arithmetic>(n: u64) -> Result {
|
||||||
use self::Result::*;
|
use self::Result::*;
|
||||||
|
|
||||||
|
@ -30,18 +31,30 @@ pub(crate) fn test<A: Arithmetic>(n: u64) -> Result {
|
||||||
return if n == 2 { Prime } else { Composite(2) };
|
return if n == 2 { Prime } else { Composite(2) };
|
||||||
}
|
}
|
||||||
|
|
||||||
let r = (n - 1) >> (n - 1).trailing_zeros();
|
// n-1 = r 2ⁱ
|
||||||
|
let i = (n - 1).trailing_zeros();
|
||||||
|
let r = (n - 1) >> i;
|
||||||
|
|
||||||
for a in BASIS.iter() {
|
for a in BASIS.iter() {
|
||||||
let mut x = a % n;
|
let a = a % n;
|
||||||
if x == 0 {
|
if a == 0 {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if A::pow(x, n - 1, n) != 1 {
|
// x = a^r mod n
|
||||||
return Pseudoprime;
|
let mut x = A::pow(a, r, n);
|
||||||
|
|
||||||
|
{
|
||||||
|
// y = ((x²)²...)² i times = x ^ (2ⁱ) = a ^ (r 2ⁱ) = x ^ (n - 1)
|
||||||
|
let mut y = x;
|
||||||
|
for _ in 0..i {
|
||||||
|
y = A::mul(y, y, n)
|
||||||
}
|
}
|
||||||
x = A::pow(x, r, n);
|
if y != 1 {
|
||||||
|
return Pseudoprime;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if x == 1 || x == n - 1 {
|
if x == 1 || x == n - 1 {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue