diff --git a/src/uu/factor/src/factor.rs b/src/uu/factor/src/factor.rs index f3fe92786d3..15af962d659 100644 --- a/src/uu/factor/src/factor.rs +++ b/src/uu/factor/src/factor.rs @@ -36,26 +36,95 @@ fn print_factors_str( return Ok(()); }; - let (factorization, remaining) = if x > BigUint::from_u32(1).unwrap() { - num_prime::nt_funcs::factors(x.clone(), None) + if x > BigUint::from_u32(1).unwrap() { + // use num_prime's factorize64 algorithm for u64 integers + if x <= BigUint::from_u64(u64::MAX).unwrap() { + let prime_factors = num_prime::nt_funcs::factorize64(x.clone().to_u64_digits()[0]); + write_result_u64(w, &x, prime_factors, print_exponents) + .map_err_context(|| translate!("factor-error-write-error"))?; + } + // use num_prime's factorize128 algorithm for u128 integers + else if x <= BigUint::from_u128(u128::MAX).unwrap() { + let rx = num_str.trim().parse::(); + let Ok(x) = rx else { + // return Ok(). it's non-fatal and we should try the next number. + show_warning!("{}: {}", num_str.maybe_quote(), rx.unwrap_err()); + set_exit_code(1); + return Ok(()); + }; + let prime_factors = num_prime::nt_funcs::factorize128(x); + write_result_u128(w, &x, prime_factors, print_exponents) + .map_err_context(|| translate!("factor-error-write-error"))?; + } + // use num_prime's fallible factorization for anything greater than u128::MAX + else { + let (prime_factors, remaining) = num_prime::nt_funcs::factors(x.clone(), None); + if let Some(_remaining) = remaining { + return Err(USimpleError::new( + 1, + translate!("factor-error-factorization-incomplete"), + )); + } + write_result_big_uint(w, &x, prime_factors, print_exponents) + .map_err_context(|| translate!("factor-error-write-error"))?; + } } else { - (BTreeMap::new(), None) - }; - - if let Some(_remaining) = remaining { - return Err(USimpleError::new( - 1, - translate!("factor-error-factorization-incomplete"), - )); + let empty_primes: BTreeMap = BTreeMap::new(); + write_result_big_uint(w, &x, empty_primes, print_exponents) + .map_err_context(|| translate!("factor-error-write-error"))?; } - write_result(w, &x, factorization, print_exponents) - .map_err_context(|| translate!("factor-error-write-error"))?; - Ok(()) } -fn write_result( +/// Writing out the prime factors for u64 integers +fn write_result_u64( + w: &mut io::BufWriter, + x: &BigUint, + factorization: BTreeMap, + print_exponents: bool, +) -> io::Result<()> { + write!(w, "{x}:")?; + for (factor, n) in factorization { + if print_exponents { + if n > 1 { + write!(w, " {factor}^{n}")?; + } else { + write!(w, " {factor}")?; + } + } else { + w.write_all(format!(" {factor}").repeat(n).as_bytes())?; + } + } + writeln!(w)?; + w.flush() +} + +/// Writing out the prime factors for u128 integers +fn write_result_u128( + w: &mut io::BufWriter, + x: &u128, + factorization: BTreeMap, + print_exponents: bool, +) -> io::Result<()> { + write!(w, "{x}:")?; + for (factor, n) in factorization { + if print_exponents { + if n > 1 { + write!(w, " {factor}^{n}")?; + } else { + write!(w, " {factor}")?; + } + } else { + w.write_all(format!(" {factor}").repeat(n).as_bytes())?; + } + } + writeln!(w)?; + w.flush() +} + +/// Writing out the prime factors for BigUint integers +fn write_result_big_uint( w: &mut io::BufWriter, x: &BigUint, factorization: BTreeMap,