1use num_bigint::{BigInt, BigUint, Sign};
16use num_integer::Integer;
17use num_traits::{One, Zero};
18use std::cmp::Ordering;
19use std::ops::{Div, DivAssign, Mul, MulAssign};
20
21#[derive(Clone, Debug, PartialEq, Eq)]
26pub struct Denom {
27 primes: [u8; Self::NUM_PRIMES],
30 remainder: Option<BigUint>,
31}
32
33impl Denom {
34 const NUM_PRIMES: usize = 24;
35 const PRIMES: [usize; Self::NUM_PRIMES] = [
36 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89,
37 ];
38
39 pub const ONE: Self = Denom {
41 primes: [0; Self::NUM_PRIMES],
42 remainder: None,
43 };
44
45 pub fn into_biguint(self) -> BigUint {
47 self.into()
48 }
49
50 pub fn to_biguint(&self) -> BigUint {
52 self.into()
53 }
54
55 fn decompose_now(mut x: BigUint) -> Self {
56 let mut primes = [0; Self::NUM_PRIMES];
57 'outer: for (i, &p) in Self::PRIMES.iter().enumerate() {
58 let p = BigUint::from(p);
59 while primes[i] != u8::MAX {
60 let (quo, rem) = x.div_rem(&p);
61 if !rem.is_zero() {
62 break;
63 }
64 x = quo;
65 primes[i] += 1;
66 if x.is_one() {
67 break 'outer;
68 }
69 }
70 }
71
72 let remainder = if x.is_one() { None } else { Some(x) };
73 Self { primes, remainder }
74 }
75
76 fn decompose_u8(mut x: u8) -> Self {
77 let mut primes = [0; Self::NUM_PRIMES];
78 'outer: for (i, &p) in Self::PRIMES.iter().enumerate() {
79 let p = p as u8;
80 while primes[i] != u8::MAX {
81 if !x.is_multiple_of(p) {
82 break;
83 }
84 x /= p;
85 primes[i] += 1;
86 if x == 1 {
87 break 'outer;
88 }
89 }
90 }
91
92 let remainder = if x == 1 { None } else { Some(x.into()) };
93 Self { primes, remainder }
94 }
95
96 fn decompose_u16(mut x: u16) -> Self {
97 let mut primes = [0; Self::NUM_PRIMES];
98 'outer: for (i, &p) in Self::PRIMES.iter().enumerate() {
99 let p = p as u16;
100 while primes[i] != u8::MAX {
101 if !x.is_multiple_of(p) {
102 break;
103 }
104 x /= p;
105 primes[i] += 1;
106 if x == 1 {
107 break 'outer;
108 }
109 }
110 }
111
112 let remainder = if x == 1 { None } else { Some(x.into()) };
113 Self { primes, remainder }
114 }
115
116 fn decompose_u32(mut x: u32) -> Self {
117 let mut primes = [0; Self::NUM_PRIMES];
118 'outer: for (i, &p) in Self::PRIMES.iter().enumerate() {
119 let p = p as u32;
120 while primes[i] != u8::MAX {
121 if !x.is_multiple_of(p) {
122 break;
123 }
124 x /= p;
125 primes[i] += 1;
126 if x == 1 {
127 break 'outer;
128 }
129 }
130 }
131
132 let remainder = if x == 1 { None } else { Some(x.into()) };
133 Self { primes, remainder }
134 }
135
136 fn decompose_u64(mut x: u64) -> Self {
137 let mut primes = [0; Self::NUM_PRIMES];
138 'outer: for (i, &p) in Self::PRIMES.iter().enumerate() {
139 let p = p as u64;
140 while primes[i] != u8::MAX {
141 if !x.is_multiple_of(p) {
142 break;
143 }
144 x /= p;
145 primes[i] += 1;
146 if x == 1 {
147 break 'outer;
148 }
149 }
150 }
151
152 let remainder = if x == 1 { None } else { Some(x.into()) };
153 Self { primes, remainder }
154 }
155
156 fn decompose_u128(mut x: u128) -> Self {
157 let mut primes = [0; Self::NUM_PRIMES];
158 'outer: for (i, &p) in Self::PRIMES.iter().enumerate() {
159 let p = p as u128;
160 while primes[i] != u8::MAX {
161 if !x.is_multiple_of(p) {
162 break;
163 }
164 x /= p;
165 primes[i] += 1;
166 if x == 1 {
167 break 'outer;
168 }
169 }
170 }
171
172 let remainder = if x == 1 { None } else { Some(x.into()) };
173 Self { primes, remainder }
174 }
175
176 fn decompose_usize(mut x: usize) -> Self {
177 let mut primes = [0; Self::NUM_PRIMES];
178 'outer: for (i, &p) in Self::PRIMES.iter().enumerate() {
179 while primes[i] != u8::MAX {
180 if !x.is_multiple_of(p) {
181 break;
182 }
183 x /= p;
184 primes[i] += 1;
185 if x == 1 {
186 break 'outer;
187 }
188 }
189 }
190
191 let remainder = if x == 1 { None } else { Some(x.into()) };
192 Self { primes, remainder }
193 }
194
195 fn decompose_mask(
196 remainder: &mut Option<BigUint>,
197 primes: &mut [u8; Self::NUM_PRIMES],
198 mask: [bool; Self::NUM_PRIMES],
199 ) {
200 let x: &mut BigUint = match remainder {
201 None => return,
202 Some(x) => x,
203 };
204
205 'outer: for (i, &p) in Self::PRIMES.iter().enumerate() {
206 if !mask[i] || primes[i] == u8::MAX {
207 continue;
208 }
209 let p = BigUint::from(p);
210 while primes[i] != u8::MAX {
211 let (quo, rem) = x.div_rem(&p);
212 if !rem.is_zero() {
213 break;
214 }
215 *x = quo;
216 primes[i] += 1;
217 if x.is_one() {
218 break 'outer;
219 }
220 }
221 }
222
223 if x.is_one() {
224 *remainder = None;
225 }
226 }
227
228 const fn decompose_small(mut x: usize) -> Self {
229 let mut primes = [0u8; Self::NUM_PRIMES];
230 let mut i = 0;
232 while x > 1 && i < Self::NUM_PRIMES {
233 let p = Self::PRIMES[i];
234 while x.is_multiple_of(p) {
235 x /= p;
236 primes[i] = primes[i].checked_add(1).unwrap();
237 }
238 i += 1;
239 }
240
241 if x != 1 {
242 panic!("Failed to decompose small integer into small prime factors.");
243 }
244 Self {
245 primes,
246 remainder: None,
247 }
248 }
249
250 const DECOMPOSED: [Self; 90] = [
252 Self::decompose_small(1),
253 Self::decompose_small(2),
254 Self::decompose_small(3),
255 Self::decompose_small(4),
256 Self::decompose_small(5),
257 Self::decompose_small(6),
258 Self::decompose_small(7),
259 Self::decompose_small(8),
260 Self::decompose_small(9),
261 Self::decompose_small(10),
262 Self::decompose_small(11),
263 Self::decompose_small(12),
264 Self::decompose_small(13),
265 Self::decompose_small(14),
266 Self::decompose_small(15),
267 Self::decompose_small(16),
268 Self::decompose_small(17),
269 Self::decompose_small(18),
270 Self::decompose_small(19),
271 Self::decompose_small(20),
272 Self::decompose_small(21),
273 Self::decompose_small(22),
274 Self::decompose_small(23),
275 Self::decompose_small(24),
276 Self::decompose_small(25),
277 Self::decompose_small(26),
278 Self::decompose_small(27),
279 Self::decompose_small(28),
280 Self::decompose_small(29),
281 Self::decompose_small(30),
282 Self::decompose_small(31),
283 Self::decompose_small(32),
284 Self::decompose_small(33),
285 Self::decompose_small(34),
286 Self::decompose_small(35),
287 Self::decompose_small(36),
288 Self::decompose_small(37),
289 Self::decompose_small(38),
290 Self::decompose_small(39),
291 Self::decompose_small(40),
292 Self::decompose_small(41),
293 Self::decompose_small(42),
294 Self::decompose_small(43),
295 Self::decompose_small(44),
296 Self::decompose_small(45),
297 Self::decompose_small(46),
298 Self::decompose_small(47),
299 Self::decompose_small(48),
300 Self::decompose_small(49),
301 Self::decompose_small(50),
302 Self::decompose_small(51),
303 Self::decompose_small(52),
304 Self::decompose_small(53),
305 Self::decompose_small(54),
306 Self::decompose_small(55),
307 Self::decompose_small(56),
308 Self::decompose_small(57),
309 Self::decompose_small(58),
310 Self::decompose_small(59),
311 Self::decompose_small(60),
312 Self::decompose_small(61),
313 Self::decompose_small(62),
314 Self::decompose_small(63),
315 Self::decompose_small(64),
316 Self::decompose_small(65),
317 Self::decompose_small(66),
318 Self::decompose_small(67),
319 Self::decompose_small(68),
320 Self::decompose_small(69),
321 Self::decompose_small(70),
322 Self::decompose_small(71),
323 Self::decompose_small(72),
324 Self::decompose_small(73),
325 Self::decompose_small(74),
326 Self::decompose_small(75),
327 Self::decompose_small(76),
328 Self::decompose_small(77),
329 Self::decompose_small(78),
330 Self::decompose_small(79),
331 Self::decompose_small(80),
332 Self::decompose_small(81),
333 Self::decompose_small(82),
334 Self::decompose_small(83),
335 Self::decompose_small(84),
336 Self::decompose_small(85),
337 Self::decompose_small(86),
338 Self::decompose_small(87),
339 Self::decompose_small(88),
340 Self::decompose_small(89),
341 Self::decompose_small(90),
342 ];
343
344 pub fn normalize(lnum: &mut BigInt, rnum: &mut BigInt, ldenom: &Self, rdenom: &Self) -> Self {
347 let mut primes = [0; Self::NUM_PRIMES];
348 let mut ltmp = 1_usize;
349 let mut rtmp = 1_usize;
350 for (i, &p) in Self::PRIMES.iter().enumerate() {
351 let lcount = ldenom.primes[i];
352 let rcount = rdenom.primes[i];
353 match lcount.cmp(&rcount) {
354 Ordering::Equal => {
355 primes[i] = lcount;
356 }
357 Ordering::Less => {
358 Self::accum_pow(lnum, &mut ltmp, p, rcount - lcount);
359 primes[i] = rcount;
360 }
361 Ordering::Greater => {
362 Self::accum_pow(rnum, &mut rtmp, p, lcount - rcount);
363 primes[i] = lcount;
364 }
365 }
366 }
367
368 *lnum *= ltmp;
369 *rnum *= rtmp;
370 let remainder = match (&ldenom.remainder, &rdenom.remainder) {
371 (None, None) => None,
372 (None, Some(r)) => {
373 *lnum *= BigInt::from_biguint(Sign::Plus, r.clone());
374 Some(r.clone())
375 }
376 (Some(l), None) => {
377 *rnum *= BigInt::from_biguint(Sign::Plus, l.clone());
378 Some(l.clone())
379 }
380 (Some(l), Some(r)) => {
381 if l == r {
382 Some(l.clone())
383 } else {
384 *lnum *= BigInt::from_biguint(Sign::Plus, r.clone());
385 *rnum *= BigInt::from_biguint(Sign::Plus, l.clone());
386 Some(l * r)
387 }
388 }
389 };
390 Denom { primes, remainder }
391 }
392
393 fn accum_pow(numerator: &mut BigInt, tmp: &mut usize, prime: usize, exponent: u8) {
396 for _ in 0..exponent {
397 match tmp.checked_mul(prime) {
398 Some(prod) => *tmp = prod,
399 None => {
400 *numerator *= *tmp;
401 *tmp = prime;
402 }
403 }
404 }
405 }
406
407 fn pow_primes(
408 this: &[u8; Self::NUM_PRIMES],
409 exponent: u32,
410 remainder: &mut Option<BigUint>,
411 ) -> [u8; Self::NUM_PRIMES] {
412 let mut primes = [0; Self::NUM_PRIMES];
413 for (i, &p) in Self::PRIMES.iter().enumerate() {
414 let product = (this[i] as u32).checked_mul(exponent).unwrap();
415 if product <= u8::MAX as u32 {
416 primes[i] = product as u8;
417 } else {
418 primes[i] = u8::MAX;
419 let factor = BigUint::from(p).pow(product - u8::MAX as u32);
420 match remainder {
421 None => *remainder = Some(factor),
422 Some(r) => *r *= factor,
423 };
424 }
425 }
426 primes
427 }
428
429 fn mul_primes(
430 lhs: &[u8; Self::NUM_PRIMES],
431 rhs: &[u8; Self::NUM_PRIMES],
432 remainder: &mut Option<BigUint>,
433 ) -> [u8; Self::NUM_PRIMES] {
434 let mut primes = [0; Self::NUM_PRIMES];
435 for (i, &p) in Self::PRIMES.iter().enumerate() {
436 let sum = lhs[i] as u32 + rhs[i] as u32;
437 if sum <= u8::MAX as u32 {
438 primes[i] = sum as u8;
439 } else {
440 primes[i] = u8::MAX;
441 let factor = BigUint::from(p).pow(sum - u8::MAX as u32);
442 match remainder {
443 None => *remainder = Some(factor),
444 Some(r) => *r *= factor,
445 };
446 }
447 }
448 primes
449 }
450
451 fn div_primes(
452 num: &[u8; Self::NUM_PRIMES],
453 denom: &[u8; Self::NUM_PRIMES],
454 mut remainder: Option<BigUint>,
455 ) -> (Self, [bool; Self::NUM_PRIMES]) {
456 let mut primes = [0; Self::NUM_PRIMES];
457 let mut mask = [false; Self::NUM_PRIMES];
458 for (i, &p) in Self::PRIMES.iter().enumerate() {
459 mask[i] = num[i] == u8::MAX;
460 if num[i] >= denom[i] {
461 primes[i] = num[i] - denom[i];
462 } else {
463 primes[i] = 0;
464 let factor = BigUint::from(p).pow(denom[i] as u32 - num[i] as u32);
465 remainder = match remainder {
466 None => Some(factor),
467 Some(r) => Some(r * factor),
468 };
469 }
470 }
471 (Denom { primes, remainder }, mask)
472 }
473
474 pub fn gcd_reduce(&mut self, num: &mut BigInt) {
477 if let Some(remainder) = &mut self.remainder {
478 let gcd = remainder.gcd(num.magnitude());
479 if !gcd.is_one() {
480 *remainder /= &gcd;
481 if remainder.is_one() {
482 self.remainder = None;
483 }
484 let gcd: BigInt = gcd.into();
485 *num /= gcd;
486 }
487 }
488
489 'outer: for (i, &p) in Self::PRIMES.iter().enumerate() {
490 if self.primes[i] != 0 {
491 let p = BigInt::from(p);
492 while self.primes[i] != 0 {
493 let (quo, rem) = num.div_rem(&p);
494 if !rem.is_zero() {
495 break;
496 }
497 *num = quo;
498 self.primes[i] -= 1;
499 if num.magnitude().is_one() {
500 break 'outer;
501 }
502 }
503 }
504 }
505 }
506}
507
508impl From<u8> for Denom {
509 fn from(value: u8) -> Denom {
510 if value == 0 {
511 panic!("Attempted to create a denominator of zero");
512 }
513 if value <= 90 {
514 return Denom::DECOMPOSED[value as usize - 1].clone();
515 }
516 Denom::decompose_u8(value)
517 }
518}
519
520impl From<u16> for Denom {
521 fn from(value: u16) -> Denom {
522 if value == 0 {
523 panic!("Attempted to create a denominator of zero");
524 }
525 if value <= 90 {
526 return Denom::DECOMPOSED[value as usize - 1].clone();
527 }
528 Denom::decompose_u16(value)
529 }
530}
531
532impl From<u32> for Denom {
533 fn from(value: u32) -> Denom {
534 if value == 0 {
535 panic!("Attempted to create a denominator of zero");
536 }
537 if value <= 90 {
538 return Denom::DECOMPOSED[value as usize - 1].clone();
539 }
540 Denom::decompose_u32(value)
541 }
542}
543
544impl From<u64> for Denom {
545 fn from(value: u64) -> Denom {
546 if value == 0 {
547 panic!("Attempted to create a denominator of zero");
548 }
549 if value <= 90 {
550 return Denom::DECOMPOSED[value as usize - 1].clone();
551 }
552 Denom::decompose_u64(value)
553 }
554}
555
556impl From<u128> for Denom {
557 fn from(value: u128) -> Denom {
558 if value == 0 {
559 panic!("Attempted to create a denominator of zero");
560 }
561 if value <= 90 {
562 return Denom::DECOMPOSED[value as usize - 1].clone();
563 }
564 Denom::decompose_u128(value)
565 }
566}
567
568impl From<usize> for Denom {
569 fn from(value: usize) -> Denom {
570 if value == 0 {
571 panic!("Attempted to create a denominator of zero");
572 }
573 if value <= 90 {
574 return Denom::DECOMPOSED[value - 1].clone();
575 }
576 Denom::decompose_usize(value)
577 }
578}
579
580impl From<BigUint> for Denom {
581 fn from(value: BigUint) -> Denom {
582 if value.is_zero() {
583 panic!("Attempted to create a denominator of zero");
584 }
585 if value <= BigUint::from(90_usize) {
586 return Denom::DECOMPOSED[TryInto::<usize>::try_into(value).unwrap() - 1].clone();
587 }
588 Denom::decompose_now(value)
589 }
590}
591
592impl From<&BigUint> for Denom {
593 fn from(value: &BigUint) -> Denom {
594 if value.is_zero() {
595 panic!("Attempted to create a denominator of zero");
596 }
597 if *value <= BigUint::from(90_usize) {
598 return Denom::DECOMPOSED[TryInto::<usize>::try_into(value).unwrap() - 1].clone();
599 }
600 Denom::decompose_now(value.clone())
601 }
602}
603
604impl From<Denom> for BigUint {
605 fn from(value: Denom) -> BigUint {
606 let mut result = match value.remainder {
607 Some(x) => x,
608 None => BigUint::ONE,
609 };
610 let mut tmp = 1_usize;
611 for (i, &count) in value.primes.iter().enumerate() {
612 let p = Denom::PRIMES[i];
613 for _ in 0..count {
614 match tmp.checked_mul(p) {
615 Some(prod) => tmp = prod,
616 None => {
617 result *= tmp;
618 tmp = p;
619 }
620 }
621 }
622 }
623 result * tmp
624 }
625}
626
627impl From<&Denom> for BigUint {
628 fn from(value: &Denom) -> BigUint {
629 let mut result = match &value.remainder {
630 Some(x) => x.clone(),
631 None => BigUint::ONE,
632 };
633 let mut tmp = 1_usize;
634 for (i, &count) in value.primes.iter().enumerate() {
635 let p = Denom::PRIMES[i];
636 for _ in 0..count {
637 match tmp.checked_mul(p) {
638 Some(prod) => tmp = prod,
639 None => {
640 result *= tmp;
641 tmp = p;
642 }
643 }
644 }
645 }
646 result * tmp
647 }
648}
649
650impl One for Denom {
651 fn one() -> Self {
652 Self::ONE
653 }
654}
655
656impl num_traits::Pow<u32> for Denom {
657 type Output = Self;
658
659 fn pow(mut self, rhs: u32) -> Self {
660 if rhs == 0 {
661 return Denom::ONE;
662 }
663 let primes = Denom::pow_primes(&self.primes, rhs, &mut self.remainder);
664 Denom {
665 primes,
666 remainder: self.remainder,
667 }
668 }
669}
670
671impl num_traits::Pow<u32> for &Denom {
672 type Output = Denom;
673
674 fn pow(self, rhs: u32) -> Denom {
675 if rhs == 0 {
676 return Denom::ONE;
677 }
678 let mut remainder = self.remainder.clone();
679 let primes = Denom::pow_primes(&self.primes, rhs, &mut remainder);
680 Denom { primes, remainder }
681 }
682}
683
684impl Mul for Denom {
685 type Output = Self;
686
687 fn mul(self, rhs: Self) -> Self {
688 let mut remainder = match (self.remainder, rhs.remainder) {
689 (None, None) => None,
690 (None, Some(r)) => Some(r),
691 (Some(l), None) => Some(l),
692 (Some(l), Some(r)) => Some(l * r),
693 };
694 let primes = Denom::mul_primes(&self.primes, &rhs.primes, &mut remainder);
695 Denom { primes, remainder }
696 }
697}
698
699impl Mul<&Denom> for Denom {
700 type Output = Self;
701
702 fn mul(self, rhs: &Denom) -> Self {
703 let mut remainder = match (self.remainder, &rhs.remainder) {
704 (None, None) => None,
705 (None, Some(r)) => Some(r.clone()),
706 (Some(l), None) => Some(l),
707 (Some(l), Some(r)) => Some(l * r),
708 };
709 let primes = Denom::mul_primes(&self.primes, &rhs.primes, &mut remainder);
710 Denom { primes, remainder }
711 }
712}
713
714impl Mul for &Denom {
715 type Output = Denom;
716
717 fn mul(self, rhs: Self) -> Denom {
718 let mut remainder = match (&self.remainder, &rhs.remainder) {
719 (None, None) => None,
720 (None, Some(r)) => Some(r.clone()),
721 (Some(l), None) => Some(l.clone()),
722 (Some(l), Some(r)) => Some(l * r),
723 };
724 let primes = Denom::mul_primes(&self.primes, &rhs.primes, &mut remainder);
725 Denom { primes, remainder }
726 }
727}
728
729impl Mul<Denom> for &Denom {
730 type Output = Denom;
731
732 fn mul(self, rhs: Denom) -> Denom {
733 let mut remainder = match (&self.remainder, rhs.remainder) {
734 (None, None) => None,
735 (None, Some(r)) => Some(r),
736 (Some(l), None) => Some(l.clone()),
737 (Some(l), Some(r)) => Some(l * r),
738 };
739 let primes = Denom::mul_primes(&self.primes, &rhs.primes, &mut remainder);
740 Denom { primes, remainder }
741 }
742}
743
744impl MulAssign for Denom {
745 fn mul_assign(&mut self, rhs: Self) {
746 match (&mut self.remainder, rhs.remainder) {
747 (_, None) => (),
748 (None, Some(r)) => self.remainder = Some(r),
749 (Some(l), Some(r)) => *l *= r,
750 };
751 self.primes = Denom::mul_primes(&self.primes, &rhs.primes, &mut self.remainder);
752 }
753}
754
755impl MulAssign<&Denom> for Denom {
756 fn mul_assign(&mut self, rhs: &Denom) {
757 match (&mut self.remainder, &rhs.remainder) {
758 (_, None) => (),
759 (None, Some(r)) => self.remainder = Some(r.clone()),
760 (Some(l), Some(r)) => *l *= r,
761 };
762 self.primes = Denom::mul_primes(&self.primes, &rhs.primes, &mut self.remainder);
763 }
764}
765
766impl Div for Denom {
767 type Output = Self;
768
769 fn div(self, rhs: Self) -> Self {
773 let (
774 Denom {
775 mut primes,
776 remainder: rhs_remainder,
777 },
778 mask,
779 ) = Denom::div_primes(&self.primes, &rhs.primes, rhs.remainder);
780
781 let mut remainder = match (self.remainder, rhs_remainder) {
782 (None, None) => None,
783 (None, Some(r)) => {
784 if !r.is_one() {
785 panic!("Attempted to divide a denominator by a non-divisor");
786 }
787 None
788 }
789 (Some(l), None) => Some(l),
790 (Some(l), Some(r)) => {
791 let (quo, rem) = l.div_rem(&r);
792 if !rem.is_zero() {
793 panic!("Attempted to divide a denominator by a non-divisor");
794 }
795 if quo.is_one() { None } else { Some(quo) }
796 }
797 };
798
799 Denom::decompose_mask(&mut remainder, &mut primes, mask);
800 Denom { primes, remainder }
801 }
802}
803
804impl Div<&Denom> for Denom {
805 type Output = Self;
806
807 fn div(self, rhs: &Denom) -> Self {
811 let (
812 Denom {
813 mut primes,
814 remainder: rhs_remainder,
815 },
816 mask,
817 ) = Denom::div_primes(&self.primes, &rhs.primes, rhs.remainder.clone());
818
819 let mut remainder = match (self.remainder, rhs_remainder) {
820 (None, None) => None,
821 (None, Some(r)) => {
822 if !r.is_one() {
823 panic!("Attempted to divide a denominator by a non-divisor");
824 }
825 None
826 }
827 (Some(l), None) => Some(l),
828 (Some(l), Some(r)) => {
829 let (quo, rem) = l.div_rem(&r);
830 if !rem.is_zero() {
831 panic!("Attempted to divide a denominator by a non-divisor");
832 }
833 if quo.is_one() { None } else { Some(quo) }
834 }
835 };
836
837 Denom::decompose_mask(&mut remainder, &mut primes, mask);
838 Denom { primes, remainder }
839 }
840}
841
842impl Div for &Denom {
843 type Output = Denom;
844
845 fn div(self, rhs: Self) -> Denom {
849 let (
850 Denom {
851 mut primes,
852 remainder: rhs_remainder,
853 },
854 mask,
855 ) = Denom::div_primes(&self.primes, &rhs.primes, rhs.remainder.clone());
856
857 let mut remainder = match (&self.remainder, rhs_remainder) {
858 (None, None) => None,
859 (None, Some(r)) => {
860 if !r.is_one() {
861 panic!("Attempted to divide a denominator by a non-divisor");
862 }
863 None
864 }
865 (Some(l), None) => Some(l.clone()),
866 (Some(l), Some(r)) => {
867 let (quo, rem) = l.div_rem(&r);
868 if !rem.is_zero() {
869 panic!("Attempted to divide a denominator by a non-divisor");
870 }
871 if quo.is_one() { None } else { Some(quo) }
872 }
873 };
874
875 Denom::decompose_mask(&mut remainder, &mut primes, mask);
876 Denom { primes, remainder }
877 }
878}
879
880impl Div<Denom> for &Denom {
881 type Output = Denom;
882
883 fn div(self, rhs: Denom) -> Denom {
887 let (
888 Denom {
889 mut primes,
890 remainder: rhs_remainder,
891 },
892 mask,
893 ) = Denom::div_primes(&self.primes, &rhs.primes, rhs.remainder);
894
895 let mut remainder = match (&self.remainder, rhs_remainder) {
896 (None, None) => None,
897 (None, Some(r)) => {
898 if !r.is_one() {
899 panic!("Attempted to divide a denominator by a non-divisor");
900 }
901 None
902 }
903 (Some(l), None) => Some(l.clone()),
904 (Some(l), Some(r)) => {
905 let (quo, rem) = l.div_rem(&r);
906 if !rem.is_zero() {
907 panic!("Attempted to divide a denominator by a non-divisor");
908 }
909 if quo.is_one() { None } else { Some(quo) }
910 }
911 };
912
913 Denom::decompose_mask(&mut remainder, &mut primes, mask);
914 Denom { primes, remainder }
915 }
916}
917
918impl DivAssign for Denom {
919 fn div_assign(&mut self, rhs: Self) {
923 let (
924 Denom {
925 primes,
926 remainder: rhs_remainder,
927 },
928 mask,
929 ) = Denom::div_primes(&self.primes, &rhs.primes, rhs.remainder);
930 self.primes = primes;
931
932 match (&mut self.remainder, rhs_remainder) {
933 (_, None) => (),
934 (None, Some(r)) => {
935 if !r.is_one() {
936 panic!("Attempted to divide a denominator by a non-divisor");
937 }
938 }
939 (Some(l), Some(r)) => {
940 let (quo, rem) = l.div_rem(&r);
941 if !rem.is_zero() {
942 panic!("Attempted to divide a denominator by a non-divisor");
943 }
944 if quo.is_one() {
945 self.remainder = None
946 } else {
947 *l = quo;
948 }
949 }
950 };
951
952 Denom::decompose_mask(&mut self.remainder, &mut self.primes, mask);
953 }
954}
955
956impl DivAssign<&Denom> for Denom {
957 fn div_assign(&mut self, rhs: &Denom) {
961 let (
962 Denom {
963 primes,
964 remainder: rhs_remainder,
965 },
966 mask,
967 ) = Denom::div_primes(&self.primes, &rhs.primes, rhs.remainder.clone());
968 self.primes = primes;
969
970 match (&mut self.remainder, rhs_remainder) {
971 (_, None) => (),
972 (None, Some(r)) => {
973 if !r.is_one() {
974 panic!("Attempted to divide a denominator by a non-divisor");
975 }
976 }
977 (Some(l), Some(r)) => {
978 let (quo, rem) = l.div_rem(&r);
979 if !rem.is_zero() {
980 panic!("Attempted to divide a denominator by a non-divisor");
981 }
982 if quo.is_one() {
983 self.remainder = None
984 } else {
985 *l = quo;
986 }
987 }
988 };
989
990 Denom::decompose_mask(&mut self.remainder, &mut self.primes, mask);
991 }
992}
993
994impl Mul<Denom> for BigInt {
995 type Output = Self;
996
997 fn mul(mut self, rhs: Denom) -> Self {
998 let mut tmp = 1_usize;
999 for (i, &p) in Denom::PRIMES.iter().enumerate() {
1000 let count = rhs.primes[i];
1001 if count != 0 {
1002 Denom::accum_pow(&mut self, &mut tmp, p, count);
1003 }
1004 }
1005
1006 self *= tmp;
1007 if let Some(remainder) = rhs.remainder {
1008 self *= BigInt::from_biguint(Sign::Plus, remainder);
1009 }
1010 self
1011 }
1012}
1013
1014impl Mul<&Denom> for BigInt {
1015 type Output = Self;
1016
1017 fn mul(mut self, rhs: &Denom) -> Self {
1018 let mut tmp = 1_usize;
1019 for (i, &p) in Denom::PRIMES.iter().enumerate() {
1020 let count = rhs.primes[i];
1021 if count != 0 {
1022 Denom::accum_pow(&mut self, &mut tmp, p, count);
1023 }
1024 }
1025
1026 self *= tmp;
1027 if let Some(remainder) = &rhs.remainder {
1028 self *= BigInt::from_biguint(Sign::Plus, remainder.clone());
1029 }
1030 self
1031 }
1032}
1033
1034impl Mul<Denom> for &BigInt {
1035 type Output = BigInt;
1036
1037 fn mul(self, rhs: Denom) -> BigInt {
1038 let mut this = self.clone();
1039 let mut tmp = 1_usize;
1040 for (i, &p) in Denom::PRIMES.iter().enumerate() {
1041 let count = rhs.primes[i];
1042 if count != 0 {
1043 Denom::accum_pow(&mut this, &mut tmp, p, count);
1044 }
1045 }
1046
1047 this *= tmp;
1048 if let Some(remainder) = rhs.remainder {
1049 this *= BigInt::from_biguint(Sign::Plus, remainder);
1050 }
1051 this
1052 }
1053}
1054
1055impl Mul<&Denom> for &BigInt {
1056 type Output = BigInt;
1057
1058 fn mul(self, rhs: &Denom) -> BigInt {
1059 let mut this = self.clone();
1060 let mut tmp = 1_usize;
1061 for (i, &p) in Denom::PRIMES.iter().enumerate() {
1062 let count = rhs.primes[i];
1063 if count != 0 {
1064 Denom::accum_pow(&mut this, &mut tmp, p, count);
1065 }
1066 }
1067
1068 this *= tmp;
1069 if let Some(remainder) = &rhs.remainder {
1070 this *= BigInt::from_biguint(Sign::Plus, remainder.clone());
1071 }
1072 this
1073 }
1074}
1075
1076impl Mul<BigInt> for Denom {
1077 type Output = BigInt;
1078
1079 fn mul(self, mut rhs: BigInt) -> BigInt {
1080 let mut tmp = 1_usize;
1081 for (i, &p) in Denom::PRIMES.iter().enumerate() {
1082 let count = self.primes[i];
1083 if count != 0 {
1084 Denom::accum_pow(&mut rhs, &mut tmp, p, count);
1085 }
1086 }
1087
1088 rhs *= tmp;
1089 if let Some(remainder) = self.remainder {
1090 rhs *= BigInt::from_biguint(Sign::Plus, remainder);
1091 }
1092 rhs
1093 }
1094}
1095
1096impl Mul<&BigInt> for Denom {
1097 type Output = BigInt;
1098
1099 fn mul(self, rhs: &BigInt) -> BigInt {
1100 let mut rhs = rhs.clone();
1101 let mut tmp = 1_usize;
1102 for (i, &p) in Denom::PRIMES.iter().enumerate() {
1103 let count = self.primes[i];
1104 if count != 0 {
1105 Denom::accum_pow(&mut rhs, &mut tmp, p, count);
1106 }
1107 }
1108
1109 rhs *= tmp;
1110 if let Some(remainder) = self.remainder {
1111 rhs *= BigInt::from_biguint(Sign::Plus, remainder);
1112 }
1113 rhs
1114 }
1115}
1116
1117impl Mul<BigInt> for &Denom {
1118 type Output = BigInt;
1119
1120 fn mul(self, mut rhs: BigInt) -> BigInt {
1121 let mut tmp = 1_usize;
1122 for (i, &p) in Denom::PRIMES.iter().enumerate() {
1123 let count = self.primes[i];
1124 if count != 0 {
1125 Denom::accum_pow(&mut rhs, &mut tmp, p, count);
1126 }
1127 }
1128
1129 rhs *= tmp;
1130 if let Some(remainder) = &self.remainder {
1131 rhs *= BigInt::from_biguint(Sign::Plus, remainder.clone());
1132 }
1133 rhs
1134 }
1135}
1136
1137impl Mul<&BigInt> for &Denom {
1138 type Output = BigInt;
1139
1140 fn mul(self, rhs: &BigInt) -> BigInt {
1141 let mut rhs = rhs.clone();
1142 let mut tmp = 1_usize;
1143 for (i, &p) in Denom::PRIMES.iter().enumerate() {
1144 let count = self.primes[i];
1145 if count != 0 {
1146 Denom::accum_pow(&mut rhs, &mut tmp, p, count);
1147 }
1148 }
1149
1150 rhs *= tmp;
1151 if let Some(remainder) = &self.remainder {
1152 rhs *= BigInt::from_biguint(Sign::Plus, remainder.clone());
1153 }
1154 rhs
1155 }
1156}
1157
1158impl MulAssign<Denom> for BigInt {
1159 fn mul_assign(&mut self, rhs: Denom) {
1160 let mut tmp = 1_usize;
1161 for (i, &p) in Denom::PRIMES.iter().enumerate() {
1162 let count = rhs.primes[i];
1163 if count != 0 {
1164 Denom::accum_pow(self, &mut tmp, p, count);
1165 }
1166 }
1167
1168 *self *= tmp;
1169 if let Some(remainder) = rhs.remainder {
1170 *self *= BigInt::from_biguint(Sign::Plus, remainder);
1171 }
1172 }
1173}
1174
1175impl MulAssign<&Denom> for BigInt {
1176 fn mul_assign(&mut self, rhs: &Denom) {
1177 let mut tmp = 1_usize;
1178 for (i, &p) in Denom::PRIMES.iter().enumerate() {
1179 let count = rhs.primes[i];
1180 if count != 0 {
1181 Denom::accum_pow(self, &mut tmp, p, count);
1182 }
1183 }
1184
1185 *self *= tmp;
1186 if let Some(remainder) = &rhs.remainder {
1187 *self *= BigInt::from_biguint(Sign::Plus, remainder.clone());
1188 }
1189 }
1190}
1191
1192#[cfg(test)]
1193mod tests {
1194 use super::*;
1195
1196 #[test]
1197 fn test_decompose_small() {
1198 for (i, x) in Denom::DECOMPOSED.iter().enumerate() {
1199 assert_eq!(x, &Denom::decompose_small(i + 1));
1200 assert_eq!(x, &Denom::from(BigUint::from(i + 1)));
1201 assert_eq!(x, &Denom::decompose_now(BigUint::from(i + 1)));
1202 }
1203 }
1204
1205 #[test]
1206 #[should_panic(expected = "Failed to decompose small integer into small prime factors.")]
1207 fn test_decompose_small_out_of_range() {
1208 assert_eq!(
1209 Denom::decompose_small(97).to_biguint(),
1210 BigUint::from(97_usize)
1211 );
1212 }
1213
1214 #[test]
1215 fn test_decompose_is_correct() {
1216 for i in 1_usize..=1000 {
1217 let bigi = BigUint::from(i);
1218 let x = Denom::from(&bigi);
1219 let mut recomposed = x.remainder.unwrap_or_else(BigUint::one);
1220 for (i, &prime) in Denom::PRIMES.iter().enumerate() {
1221 for _ in 0..x.primes[i] {
1222 recomposed *= prime;
1223 }
1224 }
1225 assert_eq!(recomposed, bigi);
1226 }
1227 }
1228
1229 #[test]
1230 fn test_decompose_known_values() {
1231 assert_eq!(
1232 Denom::from(BigUint::from(128_usize)),
1233 Denom {
1234 primes: [
1235 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1236 ],
1237 remainder: None,
1238 }
1239 );
1240 assert_eq!(
1241 Denom::from(BigUint::from(89_usize)),
1242 Denom {
1243 primes: [
1244 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
1245 ],
1246 remainder: None,
1247 }
1248 );
1249 assert_eq!(
1250 Denom::from(BigUint::from(97_usize)),
1251 Denom {
1252 primes: [
1253 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1254 ],
1255 remainder: Some(BigUint::from(97_usize)),
1256 }
1257 );
1258 assert_eq!(
1259 Denom::from(BigUint::from(97000_usize)),
1260 Denom {
1261 primes: [
1262 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1263 ],
1264 remainder: Some(BigUint::from(97_usize)),
1265 }
1266 );
1267 }
1268
1269 #[test]
1270 fn test_decompose_prime_powers() {
1271 for (i, &p) in Denom::PRIMES.iter().enumerate() {
1272 let p = BigUint::from(p);
1273 for power in 1..=255 {
1274 assert_eq!(
1275 Denom::from(p.pow(power as u32)),
1276 Denom {
1277 primes: std::array::from_fn(|j| if i == j { power } else { 0 }),
1278 remainder: None,
1279 }
1280 );
1281 }
1282 for power in 1..=64 {
1283 assert_eq!(
1284 Denom::from(p.pow(255 + power)),
1285 Denom {
1286 primes: std::array::from_fn(|j| if i == j { 255 } else { 0 }),
1287 remainder: Some(p.pow(power)),
1288 }
1289 );
1290 }
1291 }
1292 }
1293
1294 #[test]
1295 fn test_mul_prime_powers() {
1296 let p = BigUint::from(2u32);
1297 for a in 1..=256 {
1298 let denom_a = Denom::from(p.pow(a));
1299 for b in 1..=256 {
1300 let denom_b = Denom::from(p.pow(b));
1301 let denom_ab = Denom::from(p.pow(a + b));
1302 assert_eq!(&denom_a * denom_b, denom_ab);
1303 }
1304 }
1305 }
1306
1307 #[test]
1308 fn test_div_prime_powers() {
1309 let p = BigUint::from(2u32);
1310 for a in 1..=256 {
1311 let denom_a = Denom::from(p.pow(a));
1312 for b in 1..=256 {
1313 let denom_b = Denom::from(p.pow(b));
1314 let denom_ab = Denom::from(p.pow(a + b));
1315 assert_eq!(denom_ab / denom_b, denom_a);
1316 }
1317 }
1318 }
1319
1320 #[test]
1321 fn test_to_biguint() {
1322 for i in 1_usize..=1000 {
1323 let bigi = BigUint::from(i);
1324 let x = Denom::from(&bigi);
1325 assert_eq!(x.to_biguint(), bigi);
1326 }
1327 }
1328
1329 #[test]
1330 fn test_product() {
1331 let values = (100..200)
1332 .map(|i: usize| Denom::from(BigUint::from(i)))
1333 .collect::<Vec<_>>();
1334 for (i, x) in values.iter().enumerate().map(|(i, x)| (i + 100, x)) {
1335 for (j, y) in values.iter().enumerate().map(|(j, y)| (j + 100, y)) {
1336 let z = x * y;
1337 assert_eq!(z, Denom::from(BigUint::from(i * j)));
1338 for k in 0..Denom::NUM_PRIMES {
1339 assert_eq!(z.primes[k], x.primes[k] + y.primes[k]);
1340 }
1341 }
1342 }
1343 }
1344
1345 #[test]
1346 fn test_normalize() {
1347 let values = (100..200)
1348 .map(|i: usize| Denom::from(BigUint::from(i)))
1349 .collect::<Vec<_>>();
1350 for x in &values {
1351 for y in &values {
1352 let mut xnum = BigInt::one();
1353 let mut ynum = BigInt::one();
1354 let lcm = Denom::normalize(&mut xnum, &mut ynum, x, y);
1355 let lcm_bigint = lcm.to_biguint();
1356 let xnum = xnum.to_biguint().unwrap();
1357 let ynum = ynum.to_biguint().unwrap();
1358
1359 assert_eq!(xnum * x.to_biguint(), lcm_bigint);
1360 assert_eq!(ynum * y.to_biguint(), lcm_bigint);
1361 for k in 0..Denom::NUM_PRIMES {
1362 assert_eq!(lcm.primes[k], std::cmp::max(x.primes[k], y.primes[k]));
1363 }
1364 }
1365 }
1366 }
1367
1368 #[test]
1369 fn test_gcd_reduce() {
1370 let mut num = BigInt::from(-3 * 97);
1371 let mut denom = Denom::from(BigUint::from(3u32 * 5 * 97));
1372 denom.gcd_reduce(&mut num);
1373 assert_eq!(num, BigInt::from(-1));
1374 assert_eq!(denom, Denom::from(BigUint::from(5u32)));
1375 }
1376}