Skip to main content

big_num_math/nth_root/
mod.rs

1/// Variables and their meaning
2/// --------------------------------------------------
3/// B  — base (decadic)
4/// n  — root/radix degree
5/// x  — radicand
6/// y  — root/radix
7/// r  — remainder
8/// α  — next n places of radicand
9/// β  — root next increment
10/// y' — new y for next iteration
11/// r' — new r for next iteration
12use 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
25/// Computes `nth` integer root of `radicand`.
26///
27/// Returns `PlacesRow` with result or `None` for `0`ᵗʰ root.
28pub 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    // n -1
53    let nth_less = nth - 1;
54
55    // Bⁿ⁻¹
56    let bdpl = &pow_raw(base, nth_less, false);
57
58    // decadic base powered by degree
59    // base degree power
60    // Bⁿ
61    let bdp = multiplication(base, bdpl);
62
63    // degree base degree less power
64    // nBⁿ⁻¹
65    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    // root/radix
75    // y
76    let mut rax = nought_raw();
77    // remainder
78    // r
79    let mut rem = nought_raw();
80
81    let mut agen = AlphaGenerator::new(rad, nth as usize);
82
83    loop {
84        // α
85        let alpha = agen.next();
86        // operatives
87        // y', r'
88        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
130/// n >0, ⁿ√0 =0
131/// n >0, ⁿ√1 =1
132/// ¹√x =x
133fn 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,     // y
148    rem: &RawRow,     // r
149    bdp: &RawRow,     // Bⁿ
150    alpha: &[u8],     // α
151    degree: u16,      // n
152    degree_less: u16, // n -1
153    dbdlp: &RawRow,   // nBⁿ⁻¹
154    unity: &RawRow,   // 1
155
156    #[cfg(test)] outs: &mut NextTestOuts,
157) -> (RawRow, RawRow) {
158    // yⁿ⁻¹
159    let rax_pow_less = pow_raw(&rax, degree_less, false);
160
161    // Bⁿyⁿ, subtrahend
162    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    // By, widen rax
170    if is_nought_raw(&rax) == false {
171        // y' =By +β, β =0
172
173        unsafe {
174            wrax.set_len(wrax_cap);
175        };
176
177        wrax[1..].copy_from_slice(&rax);
178    }
179
180    // Bⁿr +α, limit
181    let mut lim = mul_raw(bdp, rem, false);
182    addition_sum(alpha, &mut lim, 0);
183
184    // let make initial guess, if possible
185    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    // (By +β)ⁿ -Bⁿyⁿ
212    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            // (By +β)ⁿ -Bⁿyⁿ
221            // β =0 =>(By)ⁿ -Bⁿyⁿ =0
222            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    // r' =(Bⁿr +α) -((By +β)ⁿ -Bⁿyⁿ)
235    _ = 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, // yⁿ⁻¹
247    dbdlp: &RawRow,        // nBⁿ⁻¹
248    lim: &RawRow,          // Bⁿr +α
249    #[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        // nBⁿ⁻¹ ·yⁿ⁻¹
254        let div = multiplication(dbdlp, rax_pow_less);
255
256        #[cfg(test)]
257        {
258            *div_out = div.clone();
259        }
260
261        // (Bⁿr +α) ÷(nBⁿ⁻¹ ·yⁿ⁻¹)
262        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    // seeking largest beta that
300    // (By +β)ⁿ -Bⁿyⁿ ≤ Bⁿr +α
301
302    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    // o stands for operative
308    // y' =By +β
309    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        // (By +β)ⁿ
316        let mut omax = pow_raw(&orax, degree, false);
317
318        // (By +β)ⁿ -Bⁿyⁿ
319        _ = subtraction_arithmetical(&mut omax, sub);
320
321        // (By +β)ⁿ -Bⁿyⁿ ≤ Bⁿr +α
322        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        // (By +β)ⁿ -Bⁿyⁿ ≤ Bⁿr +α
338        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
349// do not decrement beta and add to wrax each iteration
350// add first than decrement orax
351fn decr(orax: &mut RawRow, unity: &RawRow, degree: u16, sub: &RawRow, lim: &RawRow) -> RawRow {
352    // seeking largest beta that
353    // (By +β)ⁿ -Bⁿyⁿ ≤ Bⁿr +α
354    loop {
355        _ = subtraction_arithmetical(orax, unity);
356
357        // (By +β)ⁿ
358        let mut omax = pow_raw(&orax, degree, false);
359
360        // (By +β)ⁿ -Bⁿyⁿ
361        _ = subtraction_arithmetical(&mut omax, sub);
362
363        // (By +β)ⁿ -Bⁿyⁿ ≤ Bⁿr +α
364        if let Rel::Greater(_) = rel_raw(&omax, lim) {
365            continue;
366        }
367
368        return omax;
369    }
370}
371
372// Let α be the next n digits of the radicand.
373pub struct AlphaGenerator<'a> {
374    // operative number
375    onum: &'a [u8],
376    // slice index
377    ix: usize,
378    // radix size
379    ras: usize,
380    // zero
381    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            // that would mean seeking such root that is result of zero-time
389            // applied division, that means root is argument but this would
390            // be possible only for 0 and 1
391        }
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),               // ≈ 17.7
622                (9, 4, 9999),               // ≈ 9.9998
623                (9, 3, 999),                // ≈ 9.997
624                (9, 2, 99),                 // ≈ 9.95
625                (99, 2, 9999),              // ≈ 99.995
626                (21, 3, 9999),              // ≈ 21.5            
627                (20, 4, 173_479),           // ≈ 20.41
628                (2, 17, 16_777_215),        // ≈ 2.661            
629                (3, 13, 33_554_431),        // ≈ 3.79            
630                (31629, 2, 1_000_400_400),  // ≈ 31629.11
631                (45, 5, 200_300_010),       // ≈ 45.7                                
632                (5, 12, 900_900_009),       // ≈ 5.575
633                (2, 26, 90_900_009),        // ≈ 2.02                                     
634            ];
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            // rax_pow_less =3² =9
1115            // dbdlp = 3 ⋅10² =300
1116            // div = dbdlp ⋅rax_pow_less =2700
1117            // lim = 10³ ⋅2 +791 =2791
1118            // g = ⌊lim ÷div⌋ =1
1119
1120            // omax₁ =31³ =29791
1121            // omax₂ =31³ -10³ ⋅3³ =2791
1122
1123            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            // rax_pow_less =3² =9
1159            // dbdlp = 3 ⋅10² =300
1160            // div = dbdlp ⋅rax_pow_less =2700
1161            // lim = 10³ ⋅15 +874 =15874
1162            // g = ⌊lim ÷div⌋ =5
1163
1164            // omax₁ =35³ =42875
1165            // omax₂ =35³ -10³ ⋅3³ =15875
1166
1167            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            // rax_pow_less =2² =4
1203            // dbdlp = 3 ⋅10² =300
1204            // div = dbdlp ⋅rax_pow_less =1200
1205            // lim = 10³ ⋅1 +260 =1260
1206            // g = ⌊lim ÷div⌋ =1
1207
1208            // omax₁ =21³ =9261
1209            // omax₂ =21³ -10³ ⋅2³ =1261
1210
1211            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        // essentially, same as beta_is_beta_test
1370        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        // essentially, same as guess_is_beta_test
1425        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// cargo fmt & cargo test --release nth_root
1659// cargo fmt & cargo test --release --features ext-tests nth_root