1use crate::num::arithmetic::mod_pow::mul_mod_helper;
16use crate::num::arithmetic::sqrt::{sqrt_rem_2_newton, sqrt_rem_newton};
17use crate::num::arithmetic::traits::{
18 DivMod, FloorRoot, FloorSqrt, Gcd, ModMulPrecomputed, ModSub, ModSubAssign, Parity, PowerOf2,
19 SqrtRem, Square, WrappingAddAssign, WrappingMulAssign, WrappingSquare, WrappingSubAssign,
20 XMulYToZZ, XXDivModYToQR, XXSubYYToZZ,
21};
22use crate::num::basic::integers::{PrimitiveInt, USIZE_IS_U32};
23use crate::num::basic::unsigneds::PrimitiveUnsigned;
24use crate::num::conversion::traits::{ExactFrom, WrappingFrom};
25use crate::num::factorization::primes::SMALL_PRIMES;
26use crate::num::factorization::traits::{Factor, IsPrime, Primes};
27use crate::num::logic::traits::{LeadingZeros, LowMask, SignificantBits};
28use core::mem::swap;
29
30pub(crate) const MAX_FACTORS_IN_U8: usize = 4;
31pub(crate) const MAX_FACTORS_IN_U16: usize = 6;
32pub(crate) const MAX_FACTORS_IN_U32: usize = 9;
33pub(crate) const MAX_FACTORS_IN_U64: usize = 15;
34pub(crate) const MAX_FACTORS_IN_USIZE: usize = 15;
35
36#[derive(Clone, Debug, Eq, PartialEq)]
39pub struct Factors<T: PrimitiveUnsigned, const N: usize> {
40 factors: [T; N],
41 exponents: [u8; N],
42}
43
44#[derive(Clone, Debug, Eq, PartialEq)]
46pub struct FactorsIterator<T: PrimitiveUnsigned, const N: usize> {
47 i: usize,
48 factors: Factors<T, N>,
49}
50
51impl<T: PrimitiveUnsigned, const N: usize> Iterator for FactorsIterator<T, N> {
52 type Item = (T, u8);
53
54 fn next(&mut self) -> Option<(T, u8)> {
55 let e = *self.factors.exponents.get(self.i)?;
56 if e == 0 {
57 return None;
58 }
59 let f = self.factors.factors[self.i];
60 self.i += 1;
61 Some((f, e))
62 }
63}
64
65impl<T: PrimitiveUnsigned, const N: usize> IntoIterator for Factors<T, N> {
66 type IntoIter = FactorsIterator<T, N>;
67 type Item = (T, u8);
68
69 fn into_iter(self) -> FactorsIterator<T, N> {
70 FactorsIterator {
71 i: 0,
72 factors: self,
73 }
74 }
75}
76
77impl<T: PrimitiveUnsigned, const N: usize> Factors<T, N> {
78 const fn new() -> Factors<T, N> {
79 Factors {
80 factors: [T::ZERO; N],
81 exponents: [0; N],
82 }
83 }
84
85 fn insert(&mut self, factor: T, exp: u8) {
91 let mut inserting = false;
92 let mut previous_f = T::ZERO;
93 let mut previous_e = 0;
94 for (f, e) in self.factors.iter_mut().zip(self.exponents.iter_mut()) {
95 if inserting {
96 swap(&mut previous_f, f);
97 swap(&mut previous_e, e);
98 if previous_e == 0 {
99 break;
100 }
101 } else if *e == 0 {
102 *f = factor;
103 *e = exp;
104 break;
105 } else if *f == factor {
106 *e += exp;
107 break;
108 } else if *f > factor {
109 previous_f = *f;
110 previous_e = *e;
111 *f = factor;
112 *e = exp;
113 inserting = true;
114 }
115 }
116 }
117}
118
119type FactorsU8 = Factors<u8, MAX_FACTORS_IN_U8>;
120type FactorsU16 = Factors<u16, MAX_FACTORS_IN_U16>;
121type FactorsU32 = Factors<u32, MAX_FACTORS_IN_U32>;
122type FactorsU64 = Factors<u64, MAX_FACTORS_IN_U64>;
123type FactorsUsize = Factors<usize, MAX_FACTORS_IN_USIZE>;
124
125fn div_rem_precomputed_float_for_u32_factorization(a: u32, n: u32, inverse: f64) -> (u32, u32) {
128 let mut q = (f64::from(a) * inverse) as u32;
129 let r = a.wrapping_sub(q * n);
130 let ri = i32::wrapping_from(r);
131 if ri >= i32::wrapping_from(n) {
132 q += (f64::from(ri) * inverse) as u32;
133 (q + 1, a.wrapping_sub(q * n).wrapping_sub(n))
134 } else {
135 (q, r)
136 }
137}
138
139fn div_rem_precomputed_float_u64(a: u64, n: u64, npre: f64) -> (u64, u64) {
142 if a < n {
143 return (0, a);
144 }
145 if n.get_highest_bit() {
146 return (1, a.wrapping_sub(n));
147 }
148 let (mut q, r) = if n == 1 {
149 (a, 0)
150 } else {
151 let q = ((a as f64) * npre) as u64;
152 (q, a.wrapping_sub(q.wrapping_mul(n)))
153 };
154 let ri = i64::wrapping_from(r);
155 let ni = i64::wrapping_from(n);
156 if ri < ni.wrapping_neg() {
157 q -= ((-(ri as f64)) * npre) as u64;
158 } else if ri >= ni {
159 q += ((ri as f64) * npre) as u64;
160 } else if ri < 0 {
161 return (q - 1, r.wrapping_add(n));
162 } else {
163 return (q, r);
164 }
165 let r = a.wrapping_sub(q.wrapping_mul(n));
166 let ri = i64::wrapping_from(r);
167 if ri >= ni {
168 (q + 1, r.wrapping_sub(n))
169 } else if ri < 0 {
170 (q - 1, r.wrapping_add(n))
171 } else {
172 (q, r)
173 }
174}
175
176fn remove_factor_precomputed_float_u32(mut n: u32, p: u32, inverse: f64) -> (u32, u8) {
179 if p == 2 {
180 let exp = n.trailing_zeros();
181 if exp != 0 {
182 n >>= exp;
183 }
184 (n, u8::wrapping_from(exp))
185 } else {
186 let mut exp = 0;
187 while n >= p {
188 let (q, r) = div_rem_precomputed_float_for_u32_factorization(n, p, inverse);
189 if r != 0 {
190 break;
191 }
192 exp += 1;
193 n = q;
194 }
195 (n, exp)
196 }
197}
198
199fn remove_factor_precomputed_float_u64(mut n: u64, p: u64, inverse: f64) -> (u64, u8) {
202 if p == 2 {
203 let exp = u64::from(n.trailing_zeros());
204 if exp != 0 {
205 n >>= exp;
206 }
207 (n, u8::wrapping_from(exp))
208 } else {
209 let mut exp = 0;
210 while n >= p {
211 let (q, r) = div_rem_precomputed_float_u64(n, p, inverse);
212 if r != 0 {
213 break;
214 }
215 exp += 1;
216 n = q;
217 }
218 (n, exp)
219 }
220}
221
222fn factor_trial_range_u32(factors: &mut FactorsU32, mut n: u32, num_primes: usize) -> u32 {
225 for p in u32::primes().take(num_primes) {
226 if p.square() > n {
227 break;
228 }
229 let exp;
230 (n, exp) = remove_factor_precomputed_float_u32(n, p, 1.0 / f64::from(p));
231 if exp != 0 {
232 factors.insert(p, exp);
233 }
234 }
235 n
236}
237
238fn factor_trial_range_u64(factors: &mut FactorsU64, mut n: u64, num_primes: usize) -> u64 {
240 for p in u64::primes().take(num_primes) {
241 if p.square() > n {
242 break;
243 }
244 let exp;
245 (n, exp) = remove_factor_precomputed_float_u64(n, p, 1.0 / (p as f64));
246 if exp != 0 {
247 factors.insert(p, exp);
248 }
249 }
250 n
251}
252
253const POWER235_MOD63: [u8; 63] = [
254 7, 7, 4, 0, 5, 4, 0, 5, 6, 5, 4, 4, 0, 4, 4, 0, 5, 4, 5, 4, 4, 0, 5, 4, 0, 5, 4, 6, 7, 4, 0, 4,
255 4, 0, 4, 6, 7, 5, 4, 0, 4, 4, 0, 5, 4, 4, 5, 4, 0, 5, 4, 0, 4, 4, 4, 6, 4, 0, 5, 4, 0, 4, 6,
256];
257const POWER235_MOD61: [u8; 61] = [
258 7, 7, 0, 3, 1, 1, 0, 0, 2, 3, 0, 6, 1, 5, 5, 1, 1, 0, 0, 1, 3, 4, 1, 2, 2, 1, 0, 3, 2, 4, 0, 0,
259 4, 2, 3, 0, 1, 2, 2, 1, 4, 3, 1, 0, 0, 1, 1, 5, 5, 1, 6, 0, 3, 2, 0, 0, 1, 1, 3, 0, 7,
260];
261const POWER235_MOD44: [u8; 44] = [
262 7, 7, 0, 2, 3, 3, 0, 2, 2, 3, 0, 6, 7, 2, 0, 2, 3, 2, 0, 2, 3, 6, 0, 6, 2, 3, 0, 2, 2, 2, 0, 2,
263 6, 7, 0, 2, 3, 3, 0, 2, 2, 2, 0, 6,
264];
265const POWER235_MOD31: [u8; 31] =
266 [7, 7, 3, 0, 3, 5, 4, 1, 3, 1, 1, 0, 0, 0, 1, 2, 3, 0, 1, 1, 1, 0, 0, 2, 0, 5, 4, 2, 1, 2, 6];
267
268fn factor_square_u32(n: u32) -> (u32, u8) {
272 let mut t = POWER235_MOD31[(n % 31) as usize];
273 if t == 0 {
274 return (0, 0);
275 };
276 t &= POWER235_MOD44[(n % 44) as usize];
277 if t == 0 {
278 return (0, 0);
279 };
280 t &= POWER235_MOD61[(n % 61) as usize];
281 if t == 0 {
282 return (0, 0);
283 };
284 t &= POWER235_MOD63[(n % 63) as usize];
285 if t.odd() {
286 let (y, r) = n.sqrt_rem();
287 if r == 0 {
288 return (y, 2);
289 }
290 }
291 (0, 0)
292}
293
294fn factor_power23_u64(n: u64) -> (u64, u8) {
298 let mut t = POWER235_MOD31[(n % 31) as usize];
299 if t == 0 {
300 return (0, 0);
301 };
302 t &= POWER235_MOD44[(n % 44) as usize];
303 if t == 0 {
304 return (0, 0);
305 };
306 t &= POWER235_MOD61[(n % 61) as usize];
307 if t == 0 {
308 return (0, 0);
309 };
310 t &= POWER235_MOD63[(n % 63) as usize];
311 if t.odd() {
312 let (y, r) = n.sqrt_rem();
313 if r == 0 {
314 return (y, 2);
315 }
316 }
317 if t & 2 != 0 {
318 let y = n.floor_root(3);
319 if n == y.pow(3) {
320 return (y, 3);
321 }
322 }
323 (0, 0)
324}
325
326const IS_SQUARE_MOD64: [bool; 64] = [
327 true, true, false, false, true, false, false, false, false, true, false, false, false, false,
328 false, false, true, true, false, false, false, false, false, false, false, true, false, false,
329 false, false, false, false, false, true, false, false, true, false, false, false, false, true,
330 false, false, false, false, false, false, false, true, false, false, false, false, false,
331 false, false, true, false, false, false, false, false, false,
332];
333
334const IS_SQUARE_MOD65: [bool; 65] = [
335 true, true, false, false, true, false, false, false, false, true, true, false, false, false,
336 true, false, true, false, false, false, false, false, false, false, false, true, true, false,
337 false, true, true, false, false, false, false, true, true, false, false, true, true, false,
338 false, false, false, false, false, false, false, true, false, true, false, false, false, true,
339 true, false, false, false, false, true, false, false, true,
340];
341
342const IS_SQUARE_MOD63: [bool; 63] = [
343 true, true, false, false, true, false, false, true, false, true, false, false, false, false,
344 true, false, true, false, true, false, false, false, true, false, false, true, false, false,
345 true, false, false, false, false, false, false, true, true, true, false, false, false, false,
346 false, true, false, false, true, false, false, true, false, false, false, false, false, false,
347 true, false, true, false, false, false, false,
348];
349
350fn is_square_u64(x: u64) -> bool {
352 IS_SQUARE_MOD64[(x % 64) as usize]
353 && IS_SQUARE_MOD63[(x % 63) as usize]
354 && IS_SQUARE_MOD65[(x % 65) as usize]
355 && x.floor_sqrt().square() == x
356}
357
358const FLINT_ONE_LINE_MULTIPLIER: u32 = 480;
359
360fn factor_one_line_u64(mut n: u64, iters: usize) -> u64 {
362 let orig_n = n;
363 n.wrapping_mul_assign(u64::from(FLINT_ONE_LINE_MULTIPLIER));
364 let mut iin = 0;
365 let mut inn = n;
366 for _ in 0..iters {
367 if iin >= inn {
368 break;
369 }
370 let mut sqrti = inn.floor_sqrt() + 1;
371 let square = sqrti.square();
372 let mmod = square - inn;
373 if is_square_u64(mmod) {
374 sqrti -= mmod.floor_sqrt();
375 let factor = orig_n.gcd(sqrti);
376 if factor != 1 {
377 return factor;
378 }
379 }
380 iin = inn;
381 inn.wrapping_add_assign(n);
382 }
383 0
384}
385
386fn wyhash64(seed: &mut u64) -> u64 {
387 seed.wrapping_add_assign(0x60bee2bee120fc15);
388 let tmp = u128::from(*seed) * 0xa3b195354a39b70d;
389 let tmp = ((tmp >> 64) ^ tmp).wrapping_mul(0x1b03738712fad5c9);
390 u64::wrapping_from((tmp >> 64) ^ tmp)
391}
392
393struct WyhashRandomU64s {
394 seed: u64,
395}
396
397impl WyhashRandomU64s {
398 const fn new() -> WyhashRandomU64s {
399 WyhashRandomU64s {
400 seed: 0x452aee49c457bbc3,
401 }
402 }
403}
404
405impl Iterator for WyhashRandomU64s {
406 type Item = u64;
407
408 fn next(&mut self) -> Option<u64> {
409 Some(wyhash64(&mut self.seed))
410 }
411}
412
413const N_FACTOR_PP1_TABLE: [(u16, u8); 34] = [
415 (2784, 5),
416 (1208, 2),
417 (2924, 3),
418 (286, 5),
419 (58, 5),
420 (61, 4),
421 (815, 2),
422 (944, 2),
423 (61, 3),
424 (0, 0),
425 (0, 0),
426 (0, 0),
427 (0, 0),
428 (0, 0),
429 (0, 0),
430 (0, 0),
431 (0, 0),
432 (0, 0),
433 (0, 0),
434 (606, 1),
435 (2403, 1),
436 (2524, 1),
437 (2924, 1),
438 (3735, 2),
439 (669, 2),
440 (6092, 3),
441 (2179, 3),
442 (3922, 3),
443 (6717, 4),
444 (4119, 4),
445 (2288, 4),
446 (9004, 3),
447 (9004, 3),
448 (9004, 3),
449];
450
451fn pp1_pow_ui_u64(mut x: u64, exp: u64, n: u64, ninv: u64, norm: u64) -> (u64, u64) {
454 let x_orig = x;
455 let two = u64::power_of_2(norm + 1);
456 let mut y = mul_mod_helper::<u64, u128>(x, x, n, ninv, norm).mod_sub(two, n);
457 let mut bit = u64::power_of_2(exp.significant_bits() - 2);
458 while bit != 0 {
459 (x, y) = if exp & bit != 0 {
460 (
461 mul_mod_helper::<u64, u128>(x, y, n, ninv, norm).mod_sub(x_orig, n),
462 mul_mod_helper::<u64, u128>(y, y, n, ninv, norm).mod_sub(two, n),
463 )
464 } else {
465 (
466 mul_mod_helper::<u64, u128>(x, x, n, ninv, norm).mod_sub(two, n),
467 mul_mod_helper::<u64, u128>(y, x, n, ninv, norm).mod_sub(x_orig, n),
468 )
469 };
470 bit >>= 1;
471 }
472 (x, y)
473}
474
475fn pp1_factor_u64(mut n: u64, mut x: u64, norm: u64) -> u64 {
477 if norm != 0 {
478 n >>= norm;
479 x >>= norm;
480 }
481 x.mod_sub_assign(2, n);
482 if x == 0 { 0 } else { n.gcd(x) }
483}
484
485fn pp1_find_power_u64(mut x: u64, p: u64, n: u64, ninv: u64, norm: u64) -> (u64, u64, u64) {
489 let mut factor = 1;
490 let mut y = 0;
491 while factor == 1 {
492 (x, y) = pp1_pow_ui_u64(x, p, n, ninv, norm);
493 factor = pp1_factor_u64(n, x, norm);
494 }
495 (factor, x, y)
496}
497
498fn factor_pp1_u64(mut n: u64, b1: u64, c: u64) -> u64 {
501 let mut primes = u64::primes();
502 let sqrt = b1.floor_sqrt();
503 let bits0 = b1.significant_bits();
504 let norm = LeadingZeros::leading_zeros(n);
505 n <<= norm;
506 let n_inverse = u64::precompute_mod_mul_data(&n);
507 let mut x = c << norm;
508 let mut p = 0;
510 let mut old_p = 0;
511 let mut i = 0;
512 let mut old_x = 0;
513 while p < b1 {
514 let j = i + 1024;
515 old_p = p;
516 old_x = x;
517 while i < j {
518 p = primes.next().unwrap();
519 x = if p < sqrt {
520 pp1_pow_ui_u64(
521 x,
522 p.pow(u32::wrapping_from(bits0 / p.significant_bits())),
523 n,
524 n_inverse,
525 norm,
526 )
527 .0
528 } else {
529 pp1_pow_ui_u64(x, p, n, n_inverse, norm).0
530 };
531 i += 1;
532 }
533 let factor = pp1_factor_u64(n, x, norm);
534 if factor == 0 {
535 break;
536 }
537 if factor != 1 {
538 return factor;
539 }
540 }
541 if p < b1 {
542 primes.jump_after(old_p);
544 x = old_x;
545 loop {
546 p = primes.next().unwrap();
547 old_x = x;
548 x = if p < sqrt {
549 pp1_pow_ui_u64(
550 x,
551 p.pow(u32::wrapping_from(bits0 / p.significant_bits())),
552 n,
553 n_inverse,
554 norm,
555 )
556 .0
557 } else {
558 pp1_pow_ui_u64(x, p, n, n_inverse, norm).0
559 };
560 let factor = pp1_factor_u64(n, x, norm);
561 if factor == 0 {
562 break;
563 }
564 if factor != 1 {
565 return factor;
566 }
567 }
568 } else {
569 return 0;
570 }
571 pp1_find_power_u64(old_x, p, n, n_inverse, norm).0
573}
574
575fn factor_pp1_wrapper_u64(n: u64) -> u64 {
577 let bits = n.significant_bits();
578 if bits < 31 {
580 return 0;
581 }
582 let (b1, count) = N_FACTOR_PP1_TABLE[usize::wrapping_from(bits) - 31];
583 let b1 = u64::from(b1);
584 let mut state = WyhashRandomU64s::new();
585 let mask = u64::low_mask((n - 4).significant_bits());
586 let limit = n - 3;
587 for _ in 0..count {
588 let mut randint = u64::MAX;
589 while randint >= limit {
590 randint = state.next().unwrap() & mask;
591 }
592 let factor = factor_pp1_u64(n, b1, randint + 3);
593 if factor != 0 {
594 return factor;
595 }
596 }
597 0
598}
599
600#[doc(hidden)]
604fn limbs_sqrt_rem_to_out_u64(xs_hi: u64, xs_lo: u64) -> (u64, u64, u64, usize) {
605 let high = if xs_hi == 0 { xs_lo } else { xs_hi };
606 assert_ne!(high, 0);
607 let shift = LeadingZeros::leading_zeros(high) >> 1;
608 let two_shift = shift << 1;
609 if xs_hi == 0 {
610 let (sqrt_lo, rem_lo) = if shift == 0 {
611 sqrt_rem_newton::<u64, i64>(high)
612 } else {
613 let sqrt = sqrt_rem_newton::<u64, i64>(high << two_shift).0 >> shift;
614 (sqrt, high - sqrt.square())
615 };
616 (sqrt_lo, 0, rem_lo, usize::from(rem_lo != 0))
617 } else if shift == 0 {
618 let (sqrt_lo, rem_hi, rem_lo) = sqrt_rem_2_newton::<u64, i64>(xs_hi, xs_lo);
619 if rem_hi {
620 (sqrt_lo, 1, rem_lo, 2)
621 } else {
622 (sqrt_lo, 0, rem_lo, usize::from(rem_lo != 0))
623 }
624 } else {
625 let mut lo = xs_lo;
626 let hi = (high << two_shift) | (lo >> (u64::WIDTH - two_shift));
627 let sqrt_lo = sqrt_rem_2_newton::<u64, i64>(hi, lo << two_shift).0 >> shift;
628 lo.wrapping_sub_assign(sqrt_lo.wrapping_square());
629 (sqrt_lo, 0, lo, usize::from(lo != 0))
630 }
631}
632
633const FACTOR_SQUFOF_ITERS: usize = 50_000;
634const FACTOR_ONE_LINE_ITERS: usize = 40_000;
635
636fn ll_factor_squfof_u64(n_hi: u64, n_lo: u64, max_iters: usize) -> u64 {
638 let (mut sqrt_lo, mut rem_lo, num) = if n_hi != 0 {
639 let (sqrt_lo, _, rem_lo, size) = limbs_sqrt_rem_to_out_u64(n_hi, n_lo);
640 (sqrt_lo, rem_lo, size)
641 } else {
642 let (sqrt_lo, rem_lo) = n_lo.sqrt_rem();
643 (sqrt_lo, rem_lo, usize::from(sqrt_lo != 0))
644 };
645 let sqroot = sqrt_lo;
646 let mut p = sqroot;
647 let mut q = rem_lo;
648 if q == 0 || num == 0 {
649 return sqroot;
650 }
651 let l = 1 + ((p << 1).floor_sqrt() << 1);
652 let l2 = l >> 1;
653 let mut qupto = 0;
654 let mut qlast = 1u64;
655 let mut qarr = [0; 50];
656 let mut r = 0;
657 let mut finished_loop = true;
658 for i in 0..max_iters {
659 let iq = (sqroot + p) / q;
660 let pnext = iq * q - p;
661 if q <= l {
662 if q.even() {
663 qarr[qupto] = q >> 1;
664 qupto += 1;
665 if qupto >= 50 {
666 return 0;
667 }
668 } else if q <= l2 {
669 qarr[qupto] = q;
670 qupto += 1;
671 if qupto >= 50 {
672 return 0;
673 }
674 }
675 }
676 let t = qlast.wrapping_add(iq.wrapping_mul(p.wrapping_sub(pnext)));
677 qlast = q;
678 q = t;
679 p = pnext;
680 if i.odd() || !is_square_u64(q) {
681 continue;
682 }
683 r = q.floor_sqrt();
684 if qupto == 0 {
685 finished_loop = false;
686 break;
687 }
688 let mut done = true;
689 for &q in &qarr[..qupto] {
690 if r == q {
691 done = false;
692 break;
693 }
694 }
695 if done {
696 finished_loop = false;
697 break;
698 }
699 if r == 1 {
700 return 0;
701 }
702 }
703 if finished_loop {
704 return 0;
705 }
706 qlast = r;
707 p = p + r * ((sqroot - p) / r);
708 let rem_hi;
709 (rem_hi, rem_lo) = u64::x_mul_y_to_zz(p, p);
710 let sqrt_hi;
711 (sqrt_hi, sqrt_lo) = u64::xx_sub_yy_to_zz(n_hi, n_lo, rem_hi, rem_lo);
712 q = if sqrt_hi != 0 {
713 let norm = LeadingZeros::leading_zeros(qlast);
714 u64::xx_div_mod_y_to_qr(
715 (sqrt_hi << norm) + (sqrt_lo >> (u64::WIDTH - norm)),
716 sqrt_lo << norm,
717 qlast << norm,
718 )
719 .0
720 } else {
721 sqrt_lo / qlast
722 };
723 let mut finished_loop = true;
724 for _ in 0..max_iters {
725 let iq = (sqroot + p) / q;
726 let pnext = iq * q - p;
727 if p == pnext {
728 finished_loop = false;
729 break;
730 }
731 let t = qlast.wrapping_add(iq.wrapping_mul(p.wrapping_sub(pnext)));
732 qlast = q;
733 q = t;
734 p = pnext;
735 }
736 if finished_loop {
737 0
738 } else if q.even() {
739 q >> 1
740 } else {
741 q
742 }
743}
744
745fn factor_squfof_u64(n: u64, iters: usize) -> u64 {
747 let mut factor = ll_factor_squfof_u64(0, n, iters);
748 let mut finished_loop = true;
749 for &p in &SMALL_PRIMES[1..] {
750 if factor != 0 {
751 finished_loop = false;
752 break;
753 }
754 let multiplier = u64::from(p);
755 let (multn_1, multn_0) = u64::x_mul_y_to_zz(multiplier, n);
756 factor = ll_factor_squfof_u64(multn_1, multn_0, iters);
757 if factor != 0 {
758 let (quot, rem) = factor.div_mod(multiplier);
759 if rem == 0 {
760 factor = quot;
761 }
762 if factor == 1 || factor == n {
763 factor = 0;
764 }
765 }
766 }
767 if finished_loop { 0 } else { factor }
768}
769
770const FACTOR_TRIAL_PRIMES: usize = 3000;
771const FACTOR_TRIAL_CUTOFF: u32 = 27449 * 27449;
772
773impl Factor for u8 {
774 type FACTORS = FactorsU8;
775
776 fn factor(&self) -> FactorsU8 {
798 assert_ne!(*self, 0);
799 let mut n = *self;
800 let mut factors = FactorsU8::new();
801 if n == 1 {
802 return factors;
803 }
804 let zeros = n.trailing_zeros();
805 if zeros != 0 {
806 factors.insert(2, zeros as u8);
807 n >>= zeros;
808 if n == 1 {
809 return factors;
810 }
811 }
812 let mut e;
813 let (q, r) = n.div_mod(3);
814 if r == 0 {
815 e = 1;
816 n = q;
817 let (q, r) = n.div_mod(3);
818 if r == 0 {
819 e = 2;
820 n = q;
821 let (q, r) = n.div_mod(3);
822 if r == 0 {
823 e = 3;
824 n = q;
825 let (q, r) = n.div_mod(3);
826 if r == 0 {
827 e = 4;
828 n = q;
829 if n == 3 {
830 e = 5;
831 n = 1;
832 }
833 }
834 }
835 }
836 factors.insert(3, e);
837 if n == 1 {
838 return factors;
839 }
840 }
841 let (q, r) = n.div_mod(5);
842 if r == 0 {
843 e = 1;
844 n = q;
845 let (q, r) = n.div_mod(5);
846 if r == 0 {
847 e = 2;
848 n = q;
849 if n == 5 {
850 e = 3;
851 n = 1;
852 }
853 }
854 factors.insert(5, e);
855 if n == 1 {
856 return factors;
857 }
858 }
859 let (q, r) = n.div_mod(7);
860 if r == 0 {
861 e = 1;
862 n = q;
863 if n == 7 {
864 e = 2;
865 n = 1;
866 }
867 factors.insert(7, e);
868 if n == 1 {
869 return factors;
870 }
871 }
872 match n {
873 121 => {
874 factors.insert(11, 2);
875 }
876 143 => {
877 factors.insert(11, 1);
878 factors.insert(13, 1);
879 }
880 169 => {
881 factors.insert(13, 2);
882 }
883 187 => {
884 factors.insert(11, 1);
885 factors.insert(17, 1);
886 }
887 209 => {
888 factors.insert(11, 1);
889 factors.insert(19, 1);
890 }
891 221 => {
892 factors.insert(13, 1);
893 factors.insert(17, 1);
894 }
895 247 => {
896 factors.insert(13, 1);
897 factors.insert(19, 1);
898 }
899 253 => {
900 factors.insert(11, 1);
901 factors.insert(23, 1);
902 }
903 _ => {
904 factors.insert(n, 1);
905 }
906 }
907 factors
908 }
909}
910
911impl Factor for u16 {
912 type FACTORS = FactorsU16;
913
914 fn factor(&self) -> FactorsU16 {
940 let mut factors = FactorsU16::new();
941 for (f, e) in u32::from(*self).factor() {
942 factors.insert(f as u16, e);
943 }
944 factors
945 }
946}
947
948impl Factor for u32 {
949 type FACTORS = FactorsU32;
950
951 fn factor(&self) -> FactorsU32 {
982 let n = *self;
983 assert_ne!(n, 0);
984 let mut factors = FactorsU32::new();
985 let cofactor = factor_trial_range_u32(&mut factors, n, FACTOR_TRIAL_PRIMES);
986 if cofactor == 1 {
987 return factors;
988 }
989 if cofactor.is_prime() {
990 factors.insert(cofactor, 1);
991 return factors;
992 }
993 let mut factor_arr = [0; MAX_FACTORS_IN_U32];
994 let mut exp_arr = [0; MAX_FACTORS_IN_U32];
995 factor_arr[0] = cofactor;
996 let mut factors_left = 1;
997 exp_arr[0] = 1;
998 let cutoff = FACTOR_TRIAL_CUTOFF;
999 while factors_left != 0 {
1000 let mut factor = factor_arr[factors_left - 1];
1001 if factor >= cutoff {
1002 let (mut cofactor, exp) = factor_square_u32(factor);
1003 if cofactor != 0 {
1004 exp_arr[factors_left - 1] *= exp;
1005 factor = cofactor;
1006 factor_arr[factors_left - 1] = factor;
1007 }
1008 if factor >= cutoff && !factor.is_prime() {
1009 cofactor = u32::exact_from(factor_one_line_u64(
1010 u64::from(factor),
1011 FACTOR_ONE_LINE_ITERS,
1012 ));
1013 exp_arr[factors_left] = exp_arr[factors_left - 1];
1014 factor_arr[factors_left] = cofactor;
1015 factor_arr[factors_left - 1] /= cofactor;
1016 factors_left += 1;
1017 } else {
1018 factors.insert(factor, exp_arr[factors_left - 1]);
1019 factors_left -= 1;
1020 }
1021 } else {
1022 factors.insert(factor, exp_arr[factors_left - 1]);
1023 factors_left -= 1;
1024 }
1025 }
1026 factors
1027 }
1028}
1029
1030const FACTOR_ONE_LINE_MAX: u64 = 1 << 39;
1031
1032impl Factor for u64 {
1033 type FACTORS = FactorsU64;
1034
1035 fn factor(&self) -> FactorsU64 {
1066 let n = *self;
1067 assert_ne!(n, 0);
1068 let mut factors = FactorsU64::new();
1069 let cofactor = factor_trial_range_u64(&mut factors, n, FACTOR_TRIAL_PRIMES);
1070 if cofactor == 1 {
1071 return factors;
1072 }
1073 if cofactor.is_prime() {
1074 factors.insert(cofactor, 1);
1075 return factors;
1076 }
1077 let mut factor_arr = [0; MAX_FACTORS_IN_U64];
1078 let mut exp_arr = [0; MAX_FACTORS_IN_U64];
1079 factor_arr[0] = cofactor;
1080 let mut factors_left = 1;
1081 exp_arr[0] = 1;
1082 const CUTOFF: u64 = FACTOR_TRIAL_CUTOFF as u64;
1083 while factors_left != 0 {
1084 let mut factor = factor_arr[factors_left - 1];
1085 if factor >= CUTOFF {
1086 let (mut cofactor, exp) = factor_power23_u64(factor);
1087 if cofactor != 0 {
1088 exp_arr[factors_left - 1] *= exp;
1089 factor = cofactor;
1090 factor_arr[factors_left - 1] = factor;
1091 }
1092 if factor >= CUTOFF && !factor.is_prime() {
1093 cofactor = 0;
1094 if factor < FACTOR_ONE_LINE_MAX {
1095 cofactor = factor_one_line_u64(factor, FACTOR_ONE_LINE_ITERS);
1096 }
1097 if cofactor == 0 {
1098 cofactor = factor_pp1_wrapper_u64(factor);
1099 if cofactor == 0 {
1100 cofactor = factor_squfof_u64(factor, FACTOR_SQUFOF_ITERS);
1101 assert_ne!(cofactor, 0);
1102 }
1103 }
1104 exp_arr[factors_left] = exp_arr[factors_left - 1];
1105 factor_arr[factors_left] = cofactor;
1106 factor_arr[factors_left - 1] /= cofactor;
1107 factors_left += 1;
1108 } else {
1109 factors.insert(factor, exp_arr[factors_left - 1]);
1110 factors_left -= 1;
1111 }
1112 } else {
1113 factors.insert(factor, exp_arr[factors_left - 1]);
1114 factors_left -= 1;
1115 }
1116 }
1117 factors
1118 }
1119}
1120
1121impl Factor for usize {
1122 type FACTORS = FactorsUsize;
1123
1124 fn factor(&self) -> FactorsUsize {
1153 let mut factors = FactorsUsize::new();
1154 if USIZE_IS_U32 {
1155 for (f, e) in (*self as u32).factor() {
1156 factors.insert(f as usize, e);
1157 }
1158 } else {
1159 for (f, e) in (*self as u64).factor() {
1160 factors.insert(f as usize, e);
1161 }
1162 }
1163 factors
1164 }
1165}