1use std::cmp::max;
13
14use crate::{
15 addition_sum, addition_two, division, is_nought_raw, is_unity_raw, mul_raw, multiplication,
16 nought_raw, pow_raw, rel_raw, subtraction_arithmetical, unity_raw, PlacesRow, RawRow, Rel, Row,
17};
18
19#[cfg(test)]
20use tests_of_units::next::test_aides::NextTestOuts;
21
22#[cfg(test)]
23use tests_of_units::root::test_aides::RootTestOuts;
24
25pub fn root(
29 radicand: &PlacesRow,
30 nth: u16,
31 #[cfg(test)] outs: &mut RootTestOuts,
32 #[cfg(test)] no_shortcuts: bool,
33) -> Option<PlacesRow> {
34 if nth == 0 {
35 return None;
36 }
37
38 let rad = &radicand.row;
39
40 if let Some(res) = root_shortcut(
41 rad,
42 nth,
43 #[cfg(test)]
44 no_shortcuts,
45 ) {
46 return Some(res);
47 }
48
49 let base = &vec![0, 1];
50 let unity = unity_raw();
51
52 let nth_less = nth - 1;
54
55 let bdpl = &pow_raw(base, nth_less, false);
57
58 let bdp = multiplication(base, bdpl);
62
63 let dbdlp = multiplication(&new_from_num_raw!(nth), bdpl);
66
67 #[cfg(test)]
68 {
69 outs.bdp = bdp.clone();
70 outs.nth_less = nth_less;
71 outs.dbdlp = dbdlp.clone();
72 }
73
74 let mut rax = nought_raw();
77 let mut rem = nought_raw();
80
81 let mut agen = AlphaGenerator::new(rad, nth as usize);
82
83 loop {
84 let alpha = agen.next();
86 let (orax, orem) = next(
89 &rax,
90 &rem,
91 &bdp,
92 &alpha,
93 nth,
94 nth_less,
95 &dbdlp,
96 &unity,
97 #[cfg(test)]
98 &mut NextTestOuts::new(),
99 );
100
101 let orax_pow = pow_raw(&orax, nth, false);
102
103 let rel = rel_raw(&orax_pow, rad);
104 if let Rel::Greater(_) = rel {
105 #[cfg(test)]
106 {
107 outs.bcode = 1;
108 }
109
110 break;
111 }
112
113 rax = orax;
114
115 if Rel::Equal == rel {
116 #[cfg(test)]
117 {
118 outs.bcode = 2;
119 }
120
121 break;
122 }
123
124 rem = orem;
125 }
126
127 Some(Row { row: rax })
128}
129
130fn root_shortcut(rad: &RawRow, deg: u16, #[cfg(test)] skip: bool) -> Option<PlacesRow> {
134 #[cfg(test)]
135 if skip {
136 return None;
137 }
138
139 return if deg == 1 || is_nought_raw(rad) || is_unity_raw(rad) {
140 Some(PlacesRow { row: rad.clone() })
141 } else {
142 None
143 };
144}
145
146fn next(
147 rax: &RawRow, rem: &RawRow, bdp: &RawRow, alpha: &[u8], degree: u16, degree_less: u16, dbdlp: &RawRow, unity: &RawRow, #[cfg(test)] outs: &mut NextTestOuts,
157) -> (RawRow, RawRow) {
158 let rax_pow_less = pow_raw(&rax, degree_less, false);
160
161 let sub = mul_raw(bdp, multiplication(&rax_pow_less, &rax).as_slice(), false);
163
164 let wrax_cap = rax.len() + 1;
165 let mut wrax = Vec::new();
166 wrax.reserve_exact(wrax_cap);
167 wrax.push(0);
168
169 if is_nought_raw(&rax) == false {
171 unsafe {
174 wrax.set_len(wrax_cap);
175 };
176
177 wrax[1..].copy_from_slice(&rax);
178 }
179
180 let mut lim = mul_raw(bdp, rem, false);
182 addition_sum(alpha, &mut lim, 0);
183
184 let (betag, beta) = if let Some(g) = guess(
186 &rax_pow_less,
187 dbdlp,
188 &lim,
189 #[cfg(test)]
190 &mut outs.div,
191 #[cfg(test)]
192 &mut vec![],
193 ) {
194 (true, g)
195 } else {
196 (false, unity.clone())
197 };
198
199 #[cfg(test)]
200 {
201 outs.wrax = wrax.clone();
202 outs.rax_pow_less = rax_pow_less.clone();
203 outs.sub = sub.clone();
204 outs.lim = lim.clone();
205 outs.beta = beta.clone();
206 outs.betag = Some(betag);
207 }
208
209 let inc_res = incr(&wrax, &beta, unity, degree, &sub, &lim, betag);
210
211 let (rax, max) = match inc_res {
213 IncRes::Attainment((r, m)) => {
214 #[cfg(test)]
215 set_cr(&mut outs.incr);
216
217 (r, m)
218 }
219 IncRes::MaxZero => {
220 return (wrax, lim);
223 }
224 IncRes::OverGuess(mut or) => {
225 #[cfg(test)]
226 set_cr(&mut outs.decr);
227
228 let m = decr(&mut or, unity, degree, &sub, &lim);
229
230 (or, m)
231 }
232 };
233
234 _ = subtraction_arithmetical(&mut lim, &max);
236
237 return (rax, lim);
238
239 #[cfg(test)]
240 fn set_cr(cr: &mut bool) {
241 *cr = true;
242 }
243}
244
245fn guess(
246 rax_pow_less: &RawRow, dbdlp: &RawRow, lim: &RawRow, #[cfg(test)] div_out: &mut RawRow,
250 #[cfg(test)] g_out: &mut RawRow,
251) -> Option<RawRow> {
252 if !is_nought_raw(rax_pow_less.as_slice()) {
253 let div = multiplication(dbdlp, rax_pow_less);
255
256 #[cfg(test)]
257 {
258 *div_out = div.clone();
259 }
260
261 let g = division(
263 lim,
264 &div,
265 #[cfg(test)]
266 &mut vec![],
267 )
268 .1;
269
270 #[cfg(test)]
271 {
272 *g_out = g.clone();
273 }
274
275 if g.len() > 1 || g[0] > 1 {
276 return Some(g);
277 }
278 }
279
280 None
281}
282
283#[cfg_attr(test, derive(PartialEq, Debug))]
284enum IncRes {
285 OverGuess(RawRow),
286 MaxZero,
287 Attainment((RawRow, RawRow)),
288}
289
290fn incr<'a>(
291 wrax: &RawRow,
292 beta: &RawRow,
293 unity: &RawRow,
294 degree: u16,
295 sub: &RawRow,
296 lim: &RawRow,
297 betag: bool,
298) -> IncRes {
299 let wrax_len = wrax.len();
303 let beta_len = beta.len();
304 let max_len = max(wrax_len, beta_len);
305
306 let mut orax = Vec::with_capacity(max_len + 1);
307 addition_two(beta, &wrax, &mut orax);
310 let mut init_fail = true;
311
312 let mut max = Vec::with_capacity(0);
313
314 loop {
315 let mut omax = pow_raw(&orax, degree, false);
317
318 _ = subtraction_arithmetical(&mut omax, sub);
320
321 let rel = rel_raw(&omax, lim);
323 if let Rel::Greater(_) = rel {
324 if init_fail {
325 return if betag {
326 IncRes::OverGuess(orax)
327 } else {
328 IncRes::MaxZero
329 };
330 }
331
332 _ = subtraction_arithmetical(&mut orax, unity);
333
334 return IncRes::Attainment((orax, max));
335 }
336
337 if Rel::Equal == rel {
339 return IncRes::Attainment((orax, omax));
340 }
341
342 init_fail = false;
343 max = omax;
344
345 addition_sum(unity, &mut orax, 0);
346 }
347}
348
349fn decr(orax: &mut RawRow, unity: &RawRow, degree: u16, sub: &RawRow, lim: &RawRow) -> RawRow {
352 loop {
355 _ = subtraction_arithmetical(orax, unity);
356
357 let mut omax = pow_raw(&orax, degree, false);
359
360 _ = subtraction_arithmetical(&mut omax, sub);
362
363 if let Rel::Greater(_) = rel_raw(&omax, lim) {
365 continue;
366 }
367
368 return omax;
369 }
370}
371
372pub struct AlphaGenerator<'a> {
374 onum: &'a [u8],
376 ix: usize,
378 ras: usize,
380 ngh: RawRow,
382}
383
384impl<'a> AlphaGenerator<'a> {
385 pub fn new(num: &'a [u8], ras: usize) -> Self {
386 if ras == 0 {
387 panic!("0ᵗʰ root is strictly unsupported computation.");
388 }
392
393 let places = num.len();
394
395 let full_blocks = places / ras;
396 let fbs_size = full_blocks * ras;
397 let divisible = fbs_size == places;
398
399 let ix = match divisible {
400 true => places - ras,
401 false => fbs_size,
402 };
403
404 Self {
405 onum: num,
406 ras,
407 ix,
408 ngh: nought_raw(),
409 }
410 }
411
412 pub fn next(&mut self) -> &[u8] {
413 let onum = self.onum;
414
415 if onum.len() == 0 {
416 return &self.ngh;
417 }
418
419 let mut ix = self.ix;
420 let alpha = &onum[ix..];
421 self.onum = &onum[..ix];
422
423 if ix > 0 {
424 self.ix = ix - self.ras;
425 }
426
427 ix = alpha.len();
428
429 while ix > 0 {
430 ix -= 1;
431
432 let num = alpha[ix];
433 if num > 0 {
434 break;
435 }
436 }
437
438 &alpha[..=ix]
439 }
440}
441
442#[cfg(test)]
443mod tests_of_units {
444
445 pub mod root {
446
447 pub mod test_aides {
448 use crate::RawRow;
449
450 pub struct RootTestOuts {
451 pub bcode: u32,
452 pub bdp: RawRow,
453 pub nth_less: u16,
454 pub dbdlp: RawRow,
455 }
456
457 impl RootTestOuts {
458 pub fn new() -> Self {
459 Self {
460 bcode: 0,
461 bdp: vec![],
462 nth_less: u16::MAX,
463 dbdlp: vec![],
464 }
465 }
466 }
467
468 mod tests_of_units {
469 use super::RootTestOuts;
470
471 #[test]
472 fn new_test() {
473 let outs = RootTestOuts::new();
474 assert_eq!(0, outs.bcode);
475 assert_eq!(0, outs.bdp.len());
476 assert_eq!(u16::MAX, outs.nth_less);
477 assert_eq!(0, outs.dbdlp.len());
478 }
479 }
480 }
481
482 use crate::{PlacesRow, Row};
483
484 use super::super::root;
485 use test_aides::RootTestOuts;
486
487 #[test]
488 fn basic_test() {
489 let rad = new_from_num!(8);
490 let proof = new_from_num!(2);
491 let mut outs = RootTestOuts::new();
492
493 assert_eq!(Some(proof), root(&rad, 3, &mut outs, false));
494 }
495
496 #[test]
497 fn zero_root_test() {
498 let rad = new_from_num!(u32::MAX);
499 let mut outs = RootTestOuts::new();
500
501 assert_eq!(None, root(&rad, 0, &mut outs, false));
502 }
503
504 #[test]
505 fn first_root_test() {
506 let vals = [0, 1, 2, 3, 10, 100, 999, 1_000_000, 9_999_999];
507 let mut outs = RootTestOuts::new();
508
509 for &v in vals.iter() {
510 let rad = new_from_num!(v);
511 assert_eq!(root(&rad, 1, &mut outs, true), Some(rad.clone()));
512 assert_eq!(root(&rad, 1, &mut outs, false), Some(rad.clone()));
513 }
514 }
515
516 #[test]
517 fn root_of_zero_test() {
518 let vals = [1, 2, 3, 4, 5, 100, 999];
519 let mut outs = RootTestOuts::new();
520
521 let nought = PlacesRow::nought();
522 for &v in vals.iter() {
523 assert_eq!(root(&nought, v, &mut outs, true), Some(nought.clone()));
524 assert_eq!(root(&nought, v, &mut outs, false), Some(nought.clone()));
525 }
526 }
527
528 #[test]
529 fn root_of_one_test() {
530 let vals = [1, 2, 3, 4, 5, 100, 999];
531 let mut outs = RootTestOuts::new();
532
533 let unity = PlacesRow::unity();
534 for &v in vals.iter() {
535 assert_eq!(root(&unity, v, &mut outs, true), Some(unity.clone()));
536 assert_eq!(root(&unity, v, &mut outs, false), Some(unity.clone()));
537 }
538 }
539
540 #[test]
541 fn sqrt_basic_test() {
542 #[rustfmt::skip]
543 let vals = [
544 (0, [0].as_slice()),
545 (1, [1,3].as_slice()),
546 (2, [4,8].as_slice()),
547 (3, [9,15].as_slice()),
548 (4, [16,24].as_slice()),
549 (5, [25,35].as_slice()),
550 (6, [36,48].as_slice()),];
551
552 let mut outs = RootTestOuts::new();
553
554 for v in vals.iter() {
555 for &n in v.1 {
556 let proof = Some(new_from_num!(v.0));
557 let rad = new_from_num!(n);
558
559 assert_eq!(proof, root(&rad, 2, &mut outs, true));
560 assert_eq!(proof, root(&rad, 2, &mut outs, false));
561 }
562 }
563 }
564
565 #[test]
566 fn cbrt_basic_test() {
567 #[rustfmt::skip]
568 let vals = [
569 (0,[0].as_slice()),
570 (1,[1,7].as_slice()),
571 (2,[8,26].as_slice()),
572 (3,[27,63].as_slice()),
573 (4,[64,124].as_slice()),
574 (5,[125,215].as_slice())];
575
576 let mut outs = RootTestOuts::new();
577
578 for v in vals.iter() {
579 for &n in v.1 {
580 let proof = Some(new_from_num!(v.0));
581 let rad = new_from_num!(n);
582
583 assert_eq!(proof, root(&rad, 3, &mut outs, true));
584 assert_eq!(proof, root(&rad, 3, &mut outs, false));
585 }
586 }
587 }
588
589 #[test]
590 fn integer_root_test() {
591 #[rustfmt::skip]
592 let vals = [
593 (4, 4, 256),
594 (7, 5, 16_807),
595 (100, 4, 1_00_00_00_00),
596 (217, 3, 10_218_313),
597 (5560, 2, 30_913_600),
598 (1222, 3, 1_824_793_048),
599 (177, 4, 981_506_241),
600 (793, 3, 498_677_257),
601 (313, 3, 30_664_297),
602 (4, 14, 268_435_456),
603 (2, 30, 1_073_741_824),
604 (2, 31, 2147483648),
605 (4, 15, 1073741824),
606 ];
607
608 let mut outs = RootTestOuts::new();
609 for v in vals {
610 let proof = new_from_num!(v.0);
611 let rad = PlacesRow::new_from_usize(v.2);
612
613 assert_eq!(Some(proof), root(&rad, v.1, &mut outs, false));
614 }
615 }
616
617 #[test]
618 fn rounded_root_test() {
619 #[rustfmt::skip]
620 let vals = [
621 (17, 2, 312), (9, 4, 9999), (9, 3, 999), (9, 2, 99), (99, 2, 9999), (21, 3, 9999), (20, 4, 173_479), (2, 17, 16_777_215), (3, 13, 33_554_431), (31629, 2, 1_000_400_400), (45, 5, 200_300_010), (5, 12, 900_900_009), (2, 26, 90_900_009), ];
635
636 let mut outs = RootTestOuts::new();
637
638 for v in vals {
639 let proof = new_from_num!(v.0);
640 let rad = new_from_num!(v.2);
641
642 assert_eq!(Some(proof), root(&rad, v.1, &mut outs, false));
643 }
644 }
645
646 #[test]
647 fn readme_test() {
648 let mut outs = RootTestOuts::new();
649
650 let test = PlacesRow::new_from_usize(99_999_999);
651 let radicand = PlacesRow::new_from_str(
652 "999999910000003599999916000001259999987400000083999999640000000899999999",
653 )
654 .unwrap();
655 assert_eq!(Some(test), root(&radicand, 9, &mut outs, false));
656 }
657
658 #[test]
659 fn expected_escape_test() {
660 let mut outs = RootTestOuts::new();
661
662 let rad = new_from_num!(256);
663 _ = root(&rad, 4, &mut outs, false);
664 assert_eq!(2, outs.bcode);
665
666 let rad = new_from_num!(257);
667 _ = root(&rad, 4, &mut outs, false);
668 assert_eq!(1, outs.bcode);
669 }
670
671 #[test]
672 fn degree_one_test() {
673 let mut outs = RootTestOuts::new();
674 let rad = new_from_num!(0);
675
676 _ = root(&rad, 1, &mut outs, false);
677 assert_eq!(0, outs.bdp.len());
678 assert_eq!(u16::MAX, outs.nth_less);
679 assert_eq!(0, outs.dbdlp.len());
680
681 _ = root(&rad, 1, &mut outs, true);
682 assert_eq!(vec![0, 1], outs.bdp);
683 assert_eq!(0, outs.nth_less);
684 assert_eq!(vec![1], outs.dbdlp);
685 }
686
687 #[test]
688 fn computational_test() {
689 let mut outs = RootTestOuts::new();
690 let rad = new_from_num!(2);
691
692 _ = root(&rad, 9, &mut outs, false);
693
694 assert_eq!(new_from_num_raw!(1_000_000_000), outs.bdp);
695 assert_eq!(8, outs.nth_less);
696 assert_eq!(new_from_num_raw!(900_000_000), outs.dbdlp);
697 }
698
699 #[test]
700 #[cfg(feature = "ext-tests")]
701 fn load_test() {
702 let vals = [
703 ("99999999999999999999999999999999999999", 9, "16681"),
704 (
705 "1111111111111111111111111111111111111111",
706 1,
707 "1111111111111111111111111111111111111111",
708 ),
709 (
710 "25252525252525252525252525252525252525252525252525252525",
711 25,
712 "164",
713 ),
714 (
715 "7777777777777777777777777777777777777117777777777777777777777777777777777777",
716 11,
717 "7928092",
718 ),
719 ];
720
721 let mut outs = RootTestOuts::new();
722
723 for v in vals {
724 let proof = Row::new_from_str(v.2).unwrap();
725 let rad = Row::new_from_str(v.0).unwrap();
726
727 assert_eq!(Some(proof), root(&rad, v.1, &mut outs, false));
728 }
729 }
730 }
731
732 mod root_shortcut {
733 use crate::{nought_raw, unity_raw, PlacesRow, Row};
734
735 use super::super::root_shortcut;
736
737 #[test]
738 fn nought_root_test() {
739 let nought = nought_raw();
740 let proof = PlacesRow::nought();
741
742 assert_eq!(root_shortcut(&nought, u16::MAX, false), Some(proof));
743 }
744
745 #[test]
746 fn unity_root_test() {
747 let unity = unity_raw();
748 let proof = PlacesRow::unity();
749
750 assert_eq!(root_shortcut(&unity, u16::MAX, false), Some(proof));
751 }
752
753 #[test]
754 fn deg_1_test() {
755 let rad = new_from_num!(u128::MAX);
756 assert_eq!(root_shortcut(&rad.row, 1, false), Some(rad));
757 }
758
759 #[test]
760 fn none_of_cases_test() {
761 let rad = new_from_num_raw!(2);
762 assert_eq!(root_shortcut(&rad, 2, false), None);
763 }
764
765 #[test]
766 fn skip_test() {
767 let unity = nought_raw();
768 assert_eq!(root_shortcut(&unity, 1, true), None);
769 }
770 }
771
772 pub mod next {
773
774 pub mod test_aides {
775 use crate::RawRow;
776
777 pub struct NextTestSet {
778 pub rax: usize,
779 pub rem: usize,
780 pub alp: usize,
781 pub deg: u16,
782 }
783
784 impl NextTestSet {
785 pub fn rax(&self) -> RawRow {
786 new_from_num_raw!(self.rax)
787 }
788
789 pub fn rem(&self) -> RawRow {
790 new_from_num_raw!(self.rem)
791 }
792
793 pub fn bdp(&self) -> RawRow {
794 let bdp = 10usize.pow(self.deg as u32);
795 new_from_num_raw!(bdp)
796 }
797
798 pub fn alp(&self) -> RawRow {
799 new_from_num_raw!(self.alp)
800 }
801
802 pub fn deg(&self) -> u16 {
803 self.deg
804 }
805
806 pub fn dgl(&self) -> u16 {
807 self.deg - 1
808 }
809
810 pub fn dbdlp(&self) -> RawRow {
811 let deg = self.deg;
812 let dbdlp = deg * 10u16.pow((deg - 1) as u32);
813 new_from_num_raw!(dbdlp)
814 }
815 }
816
817 pub struct NextTestOuts {
818 pub wrax: RawRow,
819 pub rax_pow_less: RawRow,
820 pub sub: RawRow,
821 pub lim: RawRow,
822 pub div: RawRow,
823 pub beta: RawRow,
824 pub betag: Option<bool>,
825 pub incr: bool,
826 pub decr: bool,
827 }
828
829 impl NextTestOuts {
830 pub fn new() -> Self {
831 let empty = vec![];
832
833 NextTestOuts {
834 wrax: empty.clone(),
835 rax_pow_less: empty.clone(),
836 sub: empty.clone(),
837 lim: empty.clone(),
838 div: empty.clone(),
839 beta: empty.clone(),
840 betag: None,
841 incr: false,
842 decr: false,
843 }
844 }
845 }
846
847 #[cfg(test)]
848 mod tests_of_units {
849
850 use super::{NextTestOuts, NextTestSet};
851
852 #[test]
853 fn test_set_test() {
854 let test = NextTestSet {
855 rax: 3,
856 rem: 15,
857 alp: 133,
858 deg: 3,
859 };
860
861 assert_eq!(vec![3], test.rax());
862 assert_eq!(vec![5, 1], test.rem());
863 assert_eq!(vec![0, 0, 0, 1], test.bdp());
864 assert_eq!(vec![3, 3, 1], test.alp());
865 assert_eq!(3, test.deg());
866 assert_eq!(2, test.dgl());
867 assert_eq!(vec![0, 0, 3], test.dbdlp());
868 }
869
870 #[test]
871 fn test_outs_test() {
872 let outs = NextTestOuts::new();
873
874 assert_eq!(0, outs.wrax.len());
875 assert_eq!(0, outs.rax_pow_less.len());
876 assert_eq!(0, outs.sub.len());
877 assert_eq!(0, outs.lim.len());
878 assert_eq!(0, outs.div.len());
879 assert_eq!(0, outs.beta.len());
880 assert_eq!(None, outs.betag);
881 assert_eq!(false, outs.incr);
882 assert_eq!(false, outs.decr);
883 }
884 }
885 }
886
887 use super::super::next;
888 use crate::unity_raw;
889 use test_aides::{NextTestOuts, NextTestSet};
890
891 #[test]
892 fn basic_test() {
893 let tset = NextTestSet {
894 rax: 3,
895 rem: 15,
896 alp: 133,
897 deg: 3,
898 };
899
900 let unity = unity_raw();
901
902 let mut outs = NextTestOuts::new();
903
904 let (rax, rem) = next(
905 &tset.rax(),
906 &tset.rem(),
907 &tset.bdp(),
908 &tset.alp(),
909 tset.deg(),
910 tset.dgl(),
911 &tset.dbdlp(),
912 &unity,
913 &mut outs,
914 );
915
916 let sub = 27_000;
917 let lim = 15_133;
918 let div = 2700;
919
920 let beta = lim / div;
921 let rem_proof = lim - (34u32.pow(tset.deg() as u32) - sub);
922
923 let sub = new_from_num_raw!(sub);
924 let lim = new_from_num_raw!(lim);
925 let div = new_from_num_raw!(div);
926
927 let beta = new_from_num_raw!(beta);
928 let rem_proof = new_from_num_raw!(rem_proof);
929
930 assert_eq!(vec![0, 3], outs.wrax);
931 assert_eq!(vec![9], outs.rax_pow_less);
932 assert_eq!(sub, outs.sub);
933 assert_eq!(lim, outs.lim);
934 assert_eq!(div, outs.div);
935
936 assert_eq!(beta, outs.beta);
937 assert_eq!(Some(true), outs.betag);
938
939 assert_eq!(vec![4, 3], rax);
940 assert_eq!(rem_proof, rem);
941 }
942
943 #[test]
944 fn rax_zero_test() {
945 let tset = NextTestSet {
946 rax: 0,
947 rem: 0,
948 alp: 133,
949 deg: 3,
950 };
951
952 let unity = unity_raw();
953 let mut outs = NextTestOuts::new();
954
955 _ = next(
956 &mut tset.rax(),
957 &tset.rem(),
958 &tset.bdp(),
959 &tset.alp(),
960 tset.deg(),
961 tset.dgl(),
962 &tset.dbdlp(),
963 &unity,
964 &mut outs,
965 );
966
967 assert_eq!(vec![0], outs.wrax);
968 assert_eq!(vec![0], outs.rax_pow_less);
969 assert_eq!(vec![0], outs.sub);
970 assert_eq!(vec![3, 3, 1], outs.lim);
971 assert_eq!(Vec::<u8>::new(), outs.div);
972 assert_eq!(vec![1], outs.beta);
973 assert_eq!(Some(false), outs.betag);
974 }
975
976 #[test]
977 fn degree_one_test() {
978 let tset = NextTestSet {
979 rax: 2,
980 rem: 3,
981 alp: 222,
982 deg: 1,
983 };
984
985 let unity = unity_raw();
986
987 let mut outs = NextTestOuts::new();
988
989 _ = next(
990 &mut tset.rax(),
991 &tset.rem(),
992 &tset.bdp(),
993 &tset.alp(),
994 tset.deg(),
995 tset.dgl(),
996 &tset.dbdlp(),
997 &unity,
998 &mut outs,
999 );
1000
1001 assert_eq!(vec![0, 2], outs.wrax);
1002 assert_eq!(vec![1], outs.rax_pow_less);
1003 assert_eq!(vec![0, 2], outs.sub);
1004 assert_eq!(vec![2, 5, 2], outs.lim);
1005 assert_eq!(vec![1], outs.div);
1006 assert_eq!(vec![2, 5, 2], outs.beta);
1007 assert_eq!(Some(true), outs.betag);
1008 }
1009
1010 #[test]
1011 fn g_zero_test() {
1012 let tset = NextTestSet {
1013 rax: 2,
1014 rem: 1,
1015 alp: 199,
1016 deg: 3,
1017 };
1018
1019 let unity = unity_raw();
1020
1021 let mut outs = NextTestOuts::new();
1022
1023 _ = next(
1024 &mut tset.rax(),
1025 &tset.rem(),
1026 &tset.bdp(),
1027 &tset.alp(),
1028 tset.deg(),
1029 tset.dgl(),
1030 &tset.dbdlp(),
1031 &unity,
1032 &mut outs,
1033 );
1034
1035 assert_eq!(vec![0, 2], outs.wrax);
1036 assert_eq!(vec![4], outs.rax_pow_less);
1037 assert_eq!(vec![0, 0, 0, 8], outs.sub);
1038 assert_eq!(vec![9, 9, 1, 1], outs.lim);
1039 assert_eq!(vec![0, 0, 2, 1], outs.div);
1040 assert_eq!(vec![1], outs.beta);
1041 assert_eq!(Some(false), outs.betag);
1042 }
1043
1044 #[test]
1045 fn g_one_test() {
1046 let tset = NextTestSet {
1047 rax: 2,
1048 rem: 2,
1049 alp: 399,
1050 deg: 3,
1051 };
1052
1053 let unity = unity_raw();
1054
1055 let mut outs = NextTestOuts::new();
1056
1057 _ = next(
1058 &mut tset.rax(),
1059 &tset.rem(),
1060 &tset.bdp(),
1061 &tset.alp(),
1062 tset.deg(),
1063 tset.dgl(),
1064 &tset.dbdlp(),
1065 &unity,
1066 &mut outs,
1067 );
1068
1069 assert_eq!(vec![0, 2], outs.wrax);
1070 assert_eq!(vec![4], outs.rax_pow_less);
1071 assert_eq!(vec![0, 0, 0, 8], outs.sub);
1072 assert_eq!(vec![9, 9, 3, 2], outs.lim);
1073 assert_eq!(vec![0, 0, 2, 1], outs.div);
1074 assert_eq!(vec![1], outs.beta);
1075 assert_eq!(Some(false), outs.betag);
1076 }
1077
1078 #[test]
1079 fn g_two_test() {
1080 let tset = NextTestSet {
1081 rax: 2,
1082 rem: 2,
1083 alp: 400,
1084 deg: 3,
1085 };
1086
1087 let unity = unity_raw();
1088
1089 let mut outs = NextTestOuts::new();
1090
1091 _ = next(
1092 &mut tset.rax(),
1093 &tset.rem(),
1094 &tset.bdp(),
1095 &tset.alp(),
1096 tset.deg(),
1097 tset.dgl(),
1098 &tset.dbdlp(),
1099 &unity,
1100 &mut outs,
1101 );
1102
1103 assert_eq!(vec![0, 2], outs.wrax);
1104 assert_eq!(vec![4], outs.rax_pow_less);
1105 assert_eq!(vec![0, 0, 0, 8], outs.sub);
1106 assert_eq!(vec![0, 0, 4, 2], outs.lim);
1107 assert_eq!(vec![0, 0, 2, 1], outs.div);
1108 assert_eq!(vec![2], outs.beta);
1109 assert_eq!(Some(true), outs.betag);
1110 }
1111
1112 #[test]
1113 fn incr_test() {
1114 let tset = NextTestSet {
1124 rax: 3,
1125 rem: 2,
1126 alp: 791,
1127 deg: 3,
1128 };
1129
1130 let unity = unity_raw();
1131
1132 let mut outs = NextTestOuts::new();
1133
1134 _ = next(
1135 &mut tset.rax(),
1136 &tset.rem(),
1137 &tset.bdp(),
1138 &tset.alp(),
1139 tset.deg(),
1140 tset.dgl(),
1141 &tset.dbdlp(),
1142 &unity,
1143 &mut outs,
1144 );
1145
1146 assert_eq!(vec![9], outs.rax_pow_less);
1147 assert_eq!(vec![1, 9, 7, 2], outs.lim);
1148 assert_eq!(vec![0, 0, 0, 7, 2], outs.sub);
1149 assert_eq!(vec![1], outs.beta);
1150 assert_eq!(vec![0, 0, 7, 2], outs.div);
1151 assert_eq!(Some(false), outs.betag);
1152 assert_eq!(true, outs.incr);
1153 assert_eq!(false, outs.decr);
1154 }
1155
1156 #[test]
1157 fn decr_test() {
1158 let tset = NextTestSet {
1168 rax: 3,
1169 rem: 15,
1170 alp: 874,
1171 deg: 3,
1172 };
1173
1174 let unity = unity_raw();
1175
1176 let mut outs = NextTestOuts::new();
1177
1178 _ = next(
1179 &mut tset.rax(),
1180 &tset.rem(),
1181 &tset.bdp(),
1182 &tset.alp(),
1183 tset.deg(),
1184 tset.dgl(),
1185 &tset.dbdlp(),
1186 &unity,
1187 &mut outs,
1188 );
1189
1190 assert_eq!(vec![9], outs.rax_pow_less);
1191 assert_eq!(vec![4, 7, 8, 5, 1], outs.lim);
1192 assert_eq!(vec![0, 0, 0, 7, 2], outs.sub);
1193 assert_eq!(vec![5], outs.beta);
1194 assert_eq!(vec![0, 0, 7, 2], outs.div);
1195 assert_eq!(Some(true), outs.betag);
1196 assert_eq!(false, outs.incr);
1197 assert_eq!(true, outs.decr);
1198 }
1199
1200 #[test]
1201 fn max_zero_test() {
1202 let tset = NextTestSet {
1212 rax: 2,
1213 rem: 1,
1214 alp: 260,
1215 deg: 3,
1216 };
1217
1218 let unity = unity_raw();
1219 let mut outs = NextTestOuts::new();
1220
1221 _ = next(
1222 &mut tset.rax(),
1223 &tset.rem(),
1224 &tset.bdp(),
1225 &tset.alp(),
1226 tset.deg(),
1227 tset.dgl(),
1228 &tset.dbdlp(),
1229 &unity,
1230 &mut outs,
1231 );
1232
1233 assert_eq!(vec![4], outs.rax_pow_less);
1234 assert_eq!(vec![0, 6, 2, 1], outs.lim);
1235 assert_eq!(vec![0, 0, 0, 8], outs.sub);
1236 assert_eq!(vec![1], outs.beta);
1237 assert_eq!(vec![0, 0, 2, 1], outs.div);
1238 assert_eq!(Some(false), outs.betag);
1239 assert_eq!(false, outs.incr);
1240 assert_eq!(false, outs.decr);
1241 }
1242 }
1243
1244 mod guess {
1245
1246 use crate::{nought_raw, nth_root::guess};
1247
1248 #[test]
1249 fn rax_pow_less_zero_test() {
1250 let rax_pow_less = nought_raw();
1251 let empty = vec![];
1252 let mut div_out = vec![];
1253 let mut g_out = vec![];
1254
1255 let g = guess(&rax_pow_less, &empty, &empty, &mut div_out, &mut g_out);
1256 assert_eq!(None, g);
1257 assert_eq!(0, div_out.len());
1258 assert_eq!(0, g_out.len());
1259 }
1260
1261 #[test]
1262 fn g_zero_test() {
1263 let rax_pow_less = new_from_num_raw!(25);
1264 let dbdlp = new_from_num_raw!(200);
1265 let lim = new_from_num_raw!(4_999);
1266 let mut div_out = vec![];
1267 let mut g_out = vec![];
1268
1269 let g = guess(&rax_pow_less, &dbdlp, &lim, &mut div_out, &mut g_out);
1270 assert_eq!(None, g);
1271 assert_eq!(vec![0], g_out);
1272 assert_eq!(vec![0, 0, 0, 5], div_out);
1273 }
1274
1275 #[test]
1276 fn g_one_test() {
1277 let rax_pow_less = new_from_num_raw!(25);
1278 let dbdlp = new_from_num_raw!(200);
1279 let lim = new_from_num_raw!(5_000);
1280 let mut div_out = vec![];
1281 let mut g_out = vec![];
1282
1283 let g = guess(&rax_pow_less, &dbdlp, &lim, &mut div_out, &mut g_out);
1284 assert_eq!(None, g);
1285 assert_eq!(vec![1], g_out);
1286 assert_eq!(lim, div_out);
1287 }
1288
1289 #[test]
1290 fn g_two_test() {
1291 let rax_pow_less = new_from_num_raw!(25);
1292 let dbdlp = new_from_num_raw!(200);
1293 let lim = new_from_num_raw!(10_000);
1294 let mut div_out = vec![];
1295 let mut g_out = vec![];
1296
1297 let g = guess(&rax_pow_less, &dbdlp, &lim, &mut div_out, &mut g_out);
1298 assert_eq!(Some(vec![2]), g);
1299 assert_eq!(vec![0, 0, 0, 5], div_out);
1300 }
1301
1302 #[test]
1303 fn g_ten_test() {
1304 let rax_pow_less = new_from_num_raw!(25);
1305 let dbdlp = new_from_num_raw!(200);
1306 let lim = new_from_num_raw!(50_000);
1307 let mut div_out = vec![];
1308 let mut g_out = vec![];
1309
1310 let g = guess(&rax_pow_less, &dbdlp, &lim, &mut div_out, &mut g_out);
1311 assert_eq!(Some(vec![0, 1]), g);
1312 assert_eq!(vec![0, 0, 0, 5], div_out);
1313 }
1314 }
1315
1316 mod incr {
1317 use crate::nth_root::{incr, IncRes};
1318 use crate::unity_raw;
1319
1320 struct Incr {
1321 wrax: usize,
1322 beta: usize,
1323 degree: u16,
1324 sub: usize,
1325 limit: usize,
1326 betag: bool,
1327 }
1328
1329 impl Incr {
1330 pub fn incr(&self) -> IncRes {
1331 let wrax = new_from_num_raw!(self.wrax);
1332 let beta = new_from_num_raw!(self.beta);
1333 let sub = new_from_num_raw!(self.sub);
1334 let lim = new_from_num_raw!(self.limit);
1335
1336 let betag = self.betag;
1337 let degree = self.degree;
1338 let unity = unity_raw();
1339
1340 incr(&wrax, &beta, &unity, degree, &sub, &lim, betag)
1341 }
1342 }
1343
1344 #[test]
1345 fn guess_too_much_test() {
1346 let test = Incr {
1347 wrax: 20,
1348 beta: 3,
1349 degree: 3,
1350 sub: 66,
1351 limit: 12_100,
1352 betag: true,
1353 };
1354
1355 let res = test.incr();
1356
1357 let orax = new_from_num_raw!(23);
1358
1359 match res {
1360 IncRes::OverGuess(r) => {
1361 assert_eq!(orax, r);
1362 assert_eq!(3, r.capacity());
1363 }
1364 _ => assert!(false),
1365 }
1366 }
1367
1368 #[test]
1369 fn guess_is_beta_test1() {
1371 let test = Incr {
1372 wrax: 20,
1373 beta: 3,
1374 degree: 3,
1375 sub: 67,
1376 limit: 12_100,
1377 betag: true,
1378 };
1379
1380 let res = test.incr();
1381
1382 let rax = new_from_num_raw!(23);
1383 let max = new_from_num_raw!(12100);
1384
1385 assert_eq!(IncRes::Attainment((rax, max)), res);
1386 }
1387
1388 #[test]
1389 fn guess_is_beta_test2() {
1390 let test = Incr {
1391 wrax: 20,
1392 beta: 3,
1393 degree: 3,
1394 sub: 68,
1395 limit: 12_100,
1396 betag: true,
1397 };
1398
1399 let res = test.incr();
1400
1401 let rax = new_from_num_raw!(23);
1402 let max = new_from_num_raw!(12099);
1403
1404 assert_eq!(IncRes::Attainment((rax, max)), res);
1405 }
1406
1407 #[test]
1408 fn beta_too_much_test() {
1409 let test = Incr {
1410 wrax: 20,
1411 beta: 1,
1412 degree: 3,
1413 sub: 60,
1414 limit: 9_200,
1415 betag: false,
1416 };
1417
1418 let res = test.incr();
1419
1420 assert_eq!(IncRes::MaxZero, res);
1421 }
1422
1423 #[test]
1424 fn beta_is_beta_test1() {
1426 let test = Incr {
1427 wrax: 20,
1428 beta: 3,
1429 degree: 3,
1430 sub: 67,
1431 limit: 12_100,
1432 betag: false,
1433 };
1434
1435 let res = test.incr();
1436
1437 let rax = new_from_num_raw!(23);
1438 let max = new_from_num_raw!(12100);
1439
1440 assert_eq!(IncRes::Attainment((rax, max)), res);
1441 }
1442
1443 #[test]
1444 fn beta_is_beta_test2() {
1445 let test = Incr {
1446 wrax: 20,
1447 beta: 3,
1448 degree: 3,
1449 sub: 68,
1450 limit: 12_100,
1451 betag: false,
1452 };
1453
1454 let res = test.incr();
1455
1456 let rax = new_from_num_raw!(23);
1457 let max = new_from_num_raw!(12099);
1458
1459 assert_eq!(IncRes::Attainment((rax, max)), res);
1460 }
1461 }
1462
1463 mod decr {
1464 use crate::{unity_raw, RawRow};
1465
1466 use super::super::decr;
1467
1468 struct Decr {
1469 orax: usize,
1470 deg: u16,
1471 sub: usize,
1472 lim: usize,
1473 }
1474
1475 impl Decr {
1476 pub fn decr(&self) -> (RawRow, RawRow) {
1477 let mut orax = new_from_num_raw!(self.orax);
1478 let sub = new_from_num_raw!(self.sub);
1479 let lim = new_from_num_raw!(self.lim);
1480
1481 let unity = unity_raw();
1482 let degree = self.deg;
1483
1484 let omax = decr(&mut orax, &unity, degree, &sub, &lim);
1485 (orax, omax)
1486 }
1487 }
1488
1489 #[test]
1490 fn max_equal_lim_test() {
1491 let test = Decr {
1492 orax: 25,
1493 deg: 4,
1494 sub: 776,
1495 lim: 331_000,
1496 };
1497
1498 let (orax, omax) = test.decr();
1499
1500 let rax = new_from_num_raw!(24);
1501 let max = new_from_num_raw!(331_000);
1502
1503 assert_eq!(rax, orax);
1504 assert_eq!(max, omax);
1505 }
1506
1507 #[test]
1508 fn max_less_lim_test() {
1509 let test = Decr {
1510 orax: 25,
1511 deg: 4,
1512 sub: 777,
1513 lim: 331_000,
1514 };
1515
1516 let (orax, omax) = test.decr();
1517
1518 let rax = new_from_num_raw!(24);
1519 let max = new_from_num_raw!(330_999);
1520
1521 assert_eq!(rax, orax);
1522 assert_eq!(max, omax);
1523 }
1524
1525 #[test]
1526 fn subtracting_test() {
1527 let test = Decr {
1528 orax: 26,
1529 deg: 4,
1530 sub: 776,
1531 lim: 331_000,
1532 };
1533
1534 let (orax, omax) = test.decr();
1535
1536 let rax = new_from_num_raw!(24);
1537 let max = new_from_num_raw!(331_000);
1538
1539 assert_eq!(rax, orax);
1540 assert_eq!(max, omax);
1541 }
1542 }
1543
1544 mod alpha_generator {
1545 use super::super::AlphaGenerator;
1546
1547 use crate::nought_raw;
1548
1549 #[test]
1550 fn lesser_root_test() {
1551 let vals = [
1552 (1_234_567, 3, [1, 234, 567, 0, 0]),
1553 (11_2222_3333, 4, [11, 2222, 3333, 0, 0]),
1554 ];
1555
1556 for v in vals {
1557 let num = new_from_num_raw!(v.0);
1558 let mut generator = AlphaGenerator::new(&num, v.1);
1559
1560 for p in v.2 {
1561 let proof = new_from_num_raw!(p);
1562
1563 let next = generator.next();
1564 assert_eq!(proof, next);
1565 }
1566 }
1567 }
1568
1569 #[test]
1570 fn greater_root_test() {
1571 let vals = [
1572 (123, 4, [123, 0, 0]),
1573 (123, 11, [123, 0, 0]),
1574 (12345_67890, 11, [12345_67890, 0, 0]),
1575 ];
1576
1577 for v in vals {
1578 let num = new_from_num_raw!(v.0);
1579 let mut generator = AlphaGenerator::new(&num, v.1);
1580
1581 for p in v.2 {
1582 let proof = new_from_num_raw!(p);
1583
1584 let next = generator.next();
1585 assert_eq!(proof, next);
1586 }
1587 }
1588 }
1589
1590 #[test]
1591 fn divisible_by_root_test() {
1592 let vals = [
1593 (1_234_567, 7, [1_234_567, 0, 0, 0, 0, 0]),
1594 (11_2222_3333, 2, [11, 22, 22, 33, 33, 0]),
1595 (333_444_555, 3, [333, 444, 555, 0, 0, 0]),
1596 ];
1597
1598 for v in vals {
1599 let num = new_from_num_raw!(v.0);
1600 let mut generator = AlphaGenerator::new(&num, v.1);
1601
1602 for p in v.2 {
1603 let proof = new_from_num_raw!(p);
1604
1605 let next = generator.next();
1606 assert_eq!(proof, next);
1607 }
1608 }
1609 }
1610
1611 #[test]
1612 fn zero_num_test() {
1613 let number = [0];
1614 let root = 1;
1615
1616 let mut generator = AlphaGenerator::new(number.as_slice(), root);
1617
1618 let proof = nought_raw();
1619 for _ in 0..3 {
1620 let next = generator.next();
1621 assert_eq!(proof, next);
1622 }
1623 }
1624
1625 #[test]
1626 fn zero_place_omission_test() {
1627 let vals = [
1628 (1_000_000, 3, [1, 0, 0]),
1629 (1_100_100, 3, [1, 100, 100]),
1630 (1_010_010, 3, [1, 10, 10]),
1631 (1_001_001, 3, [1, 1, 1]),
1632 ];
1633
1634 for v in vals {
1635 let num = new_from_num_raw!(v.0);
1636 let mut generator = AlphaGenerator::new(&num, v.1);
1637
1638 for p in v.2 {
1639 let proof = new_from_num_raw!(p);
1640
1641 let next = generator.next();
1642 assert_eq!(proof, next);
1643 }
1644 }
1645 }
1646
1647 #[test]
1648 #[should_panic(expected = "0ᵗʰ root is strictly unsupported computation.")]
1649 fn zero_root_test() {
1650 let number = new_from_num_raw!(u32::MAX);
1651 let root = 0;
1652
1653 _ = AlphaGenerator::new(&number, root);
1654 }
1655 }
1656}
1657
1658