1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-08-04 23:17:46 +00:00

factor: Move recursive factoring logic from rho to factor

No functional change, but prepares a coming optimisation.
This commit is contained in:
nicoo 2020-06-25 03:38:23 +02:00
parent bd4d6fcac5
commit 6713d2ad62
2 changed files with 33 additions and 35 deletions

View file

@ -11,6 +11,7 @@ use std::collections::BTreeMap;
use std::fmt;
use std::ops;
use crate::numeric::{Arithmetic, Montgomery};
use crate::{miller_rabin, rho, table};
pub struct Factors {
@ -67,6 +68,33 @@ impl fmt::Display for Factors {
}
}
fn _factor<A: Arithmetic>(num: u64) -> Factors {
use miller_rabin::Result::*;
// Shadow the name, so the recursion automatically goes from “Big” arithmetic to small.
let _factor = |n| {
// TODO: Optimise with 32 and 64b versions
_factor::<A>(n)
};
if num == 1 {
return Factors::one();
}
let n = A::new(num);
let divisor = match miller_rabin::test::<A>(n) {
Prime => {
return Factors::prime(num);
}
Composite(d) => d,
Pseudoprime => rho::find_divisor::<A>(n),
};
let mut factors = _factor(divisor);
factors *= _factor(num / divisor);
factors
}
pub fn factor(mut n: u64) -> Factors {
let mut factors = Factors::one();
@ -88,8 +116,10 @@ pub fn factor(mut n: u64) -> Factors {
let (f, n) = table::factor(n);
factors *= f;
if n >= table::NEXT_PRIME {
factors *= rho::factor(n);
if n < (1 << 32) {
factors *= _factor::<Montgomery>(n);
} else {
factors *= _factor::<Montgomery>(n);
}
factors

View file

@ -11,11 +11,9 @@ use rand::rngs::SmallRng;
use rand::{thread_rng, SeedableRng};
use std::cmp::{max, min};
use crate::miller_rabin::Result::*;
use crate::numeric::*;
use crate::{miller_rabin, Factors};
fn find_divisor<A: Arithmetic>(n: A) -> u64 {
pub(crate) fn find_divisor<A: Arithmetic>(n: A) -> u64 {
#![allow(clippy::many_single_char_names)]
let mut rand = {
let range = Uniform::new(1, n.modulus());
@ -47,33 +45,3 @@ fn find_divisor<A: Arithmetic>(n: A) -> u64 {
}
}
}
fn _factor<A: Arithmetic>(num: u64) -> Factors {
// Shadow the name, so the recursion automatically goes from “Big” arithmetic to small.
let _factor = |n| {
// TODO: Optimise with 32 and 64b versions
_factor::<A>(n)
};
if num == 1 {
return Factors::one();
}
let n = A::new(num);
let divisor = match miller_rabin::test::<A>(n) {
Prime => {
return Factors::prime(num);
}
Composite(d) => d,
Pseudoprime => find_divisor::<A>(n),
};
let mut factors = _factor(divisor);
factors *= _factor(num / divisor);
factors
}
pub(crate) fn factor(n: u64) -> Factors {
_factor::<Montgomery>(n)
}