Skip to main content

malachite_base/num/arithmetic/
root.rs

1// Copyright © 2026 Mikhail Hogrefe
2//
3// Uses code adopted from the FLINT Library.
4//
5//      Copyright © 2015 William Hart
6//
7//      Copyright © 2015 Fredrik Johansson
8//
9//      Copyright © 2015 Kushagra Singh
10//
11// This file is part of Malachite.
12//
13// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
14// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
15// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
16
17#[cfg(feature = "test_build")]
18use crate::num::arithmetic::sqrt::floor_inverse_checked_binary;
19#[cfg(feature = "test_build")]
20use crate::num::arithmetic::traits::DivRound;
21use crate::num::arithmetic::traits::{
22    CeilingRoot, CeilingRootAssign, CeilingSqrt, CheckedRoot, CheckedSqrt, DivMod, FloorRoot,
23    FloorRootAssign, FloorSqrt, Parity, Pow, PowerOf2, RootAssignRem, RootRem, SqrtRem, XMulYToZZ,
24};
25use crate::num::basic::floats::PrimitiveFloat;
26use crate::num::basic::integers::{PrimitiveInt, USIZE_IS_U32};
27use crate::num::basic::unsigneds::PrimitiveUnsigned;
28#[cfg(feature = "test_build")]
29use crate::num::conversion::traits::SplitInHalf;
30use crate::num::conversion::traits::{
31    RawMantissaAndExponent, RoundingFrom, SaturatingFrom, WrappingFrom,
32};
33use crate::num::logic::traits::{LowMask, SignificantBits};
34use crate::rounding_modes::RoundingMode::*;
35use core::cmp::Ordering::*;
36
37const U8_CUBES: [u8; 7] = [0, 1, 8, 27, 64, 125, 216];
38
39// This section is created by max_base.rs.
40const MAX_BASE_8: [u8; 8] = [0, 255, 15, 6, 3, 3, 2, 2];
41
42const MAX_POWER_8: [u8; 8] = [0, 255, 225, 216, 81, 243, 64, 128];
43
44const MAX_BASE_16: [u16; 16] = [0, 65535, 255, 40, 15, 9, 6, 4, 3, 3, 3, 2, 2, 2, 2, 2];
45
46const MAX_POWER_16: [u16; 16] = [
47    0, 65535, 65025, 64000, 50625, 59049, 46656, 16384, 6561, 19683, 59049, 2048, 4096, 8192,
48    16384, 32768,
49];
50
51const MAX_BASE_32: [u32; 32] = [
52    0, 4294967295, 65535, 1625, 255, 84, 40, 23, 15, 11, 9, 7, 6, 5, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2,
53    2, 2, 2, 2, 2, 2, 2, 2,
54];
55
56const MAX_POWER_32: [u32; 32] = [
57    0, 4294967295, 4294836225, 4291015625, 4228250625, 4182119424, 4096000000, 3404825447,
58    2562890625, 2357947691, 3486784401, 1977326743, 2176782336, 1220703125, 268435456, 1073741824,
59    43046721, 129140163, 387420489, 1162261467, 3486784401, 2097152, 4194304, 8388608, 16777216,
60    33554432, 67108864, 134217728, 268435456, 536870912, 1073741824, 2147483648,
61];
62
63const MAX_BASE_64: [u64; 64] = [
64    0,
65    18446744073709551615,
66    4294967295,
67    2642245,
68    65535,
69    7131,
70    1625,
71    565,
72    255,
73    138,
74    84,
75    56,
76    40,
77    30,
78    23,
79    19,
80    15,
81    13,
82    11,
83    10,
84    9,
85    8,
86    7,
87    6,
88    6,
89    5,
90    5,
91    5,
92    4,
93    4,
94    4,
95    4,
96    3,
97    3,
98    3,
99    3,
100    3,
101    3,
102    3,
103    3,
104    3,
105    2,
106    2,
107    2,
108    2,
109    2,
110    2,
111    2,
112    2,
113    2,
114    2,
115    2,
116    2,
117    2,
118    2,
119    2,
120    2,
121    2,
122    2,
123    2,
124    2,
125    2,
126    2,
127    2,
128];
129
130const MAX_POWER_64: [u64; 64] = [
131    0,
132    18446744073709551615,
133    18446744065119617025,
134    18446724184312856125,
135    18445618199572250625,
136    18439629140666724651,
137    18412815093994140625,
138    18379730316001328125,
139    17878103347812890625,
140    18151468971815029248,
141    17490122876598091776,
142    16985107389382393856,
143    16777216000000000000,
144    15943230000000000000,
145    11592836324538749809,
146    15181127029874798299,
147    6568408355712890625,
148    8650415919381337933,
149    5559917313492231481,
150    10000000000000000000,
151    12157665459056928801,
152    9223372036854775808,
153    3909821048582988049,
154    789730223053602816,
155    4738381338321616896,
156    298023223876953125,
157    1490116119384765625,
158    7450580596923828125,
159    72057594037927936,
160    288230376151711744,
161    1152921504606846976,
162    4611686018427387904,
163    1853020188851841,
164    5559060566555523,
165    16677181699666569,
166    50031545098999707,
167    150094635296999121,
168    450283905890997363,
169    1350851717672992089,
170    4052555153018976267,
171    12157665459056928801,
172    2199023255552,
173    4398046511104,
174    8796093022208,
175    17592186044416,
176    35184372088832,
177    70368744177664,
178    140737488355328,
179    281474976710656,
180    562949953421312,
181    1125899906842624,
182    2251799813685248,
183    4503599627370496,
184    9007199254740992,
185    18014398509481984,
186    36028797018963968,
187    72057594037927936,
188    144115188075855872,
189    288230376151711744,
190    576460752303423488,
191    1152921504606846976,
192    2305843009213693952,
193    4611686018427387904,
194    9223372036854775808,
195];
196
197const MAX_BASE_128: [u128; 128] = [
198    0,
199    340282366920938463463374607431768211455,
200    18446744073709551615,
201    6981463658331,
202    4294967295,
203    50859008,
204    2642245,
205    319557,
206    65535,
207    19112,
208    7131,
209    3183,
210    1625,
211    920,
212    565,
213    370,
214    255,
215    184,
216    138,
217    106,
218    84,
219    68,
220    56,
221    47,
222    40,
223    34,
224    30,
225    26,
226    23,
227    21,
228    19,
229    17,
230    15,
231    14,
232    13,
233    12,
234    11,
235    11,
236    10,
237    9,
238    9,
239    8,
240    8,
241    7,
242    7,
243    7,
244    6,
245    6,
246    6,
247    6,
248    5,
249    5,
250    5,
251    5,
252    5,
253    5,
254    4,
255    4,
256    4,
257    4,
258    4,
259    4,
260    4,
261    4,
262    3,
263    3,
264    3,
265    3,
266    3,
267    3,
268    3,
269    3,
270    3,
271    3,
272    3,
273    3,
274    3,
275    3,
276    3,
277    3,
278    3,
279    2,
280    2,
281    2,
282    2,
283    2,
284    2,
285    2,
286    2,
287    2,
288    2,
289    2,
290    2,
291    2,
292    2,
293    2,
294    2,
295    2,
296    2,
297    2,
298    2,
299    2,
300    2,
301    2,
302    2,
303    2,
304    2,
305    2,
306    2,
307    2,
308    2,
309    2,
310    2,
311    2,
312    2,
313    2,
314    2,
315    2,
316    2,
317    2,
318    2,
319    2,
320    2,
321    2,
322    2,
323    2,
324    2,
325    2,
326];
327
328const MAX_POWER_128: [u128; 128] = [
329    0,
330    340282366920938463463374607431768211455,
331    340282366920938463426481119284349108225,
332    340282366920856711588743492508790678691,
333    340282366604025813516997721482669850625,
334    340282351457171161640582485552312352768,
335    340281633132112807150397932954950015625,
336    340281506971235808117106851925354131693,
337    340240830764391036687105719527812890625,
338    340216388952569572744243119867142602752,
339    340019922845325450206316382040251071801,
340    339784078391451014674643196649809097167,
341    339031759685618453659117221832275390625,
342    338253076642491662461829120000000000000,
343    337814486488938281014651876763916015625,
344    333446267951815307088493000000000000000,
345    319626579315078487616775634918212890625,
346    317616452802997733092688724349413228544,
347    329475825834763755052723200291095445504,
348    302559950208758936970093677790372560896,
349    305904398238499908683087849324518834176,
350    303869538891536196286006028740295917568,
351    288493873028852398739253829029106548736,
352    287243845682065590744605010781602099023,
353    281474976710656000000000000000000000000,
354    193630125104980427932766033374162714624,
355    254186582832900000000000000000000000000,
356    160059109085386090080713531498405298176,
357    134393854047545109686936775588697536481,
358    220983347100817338120002444455525554981,
359    230466617897195215045509519405933293401,
360    139288917338851014461418017489467720433,
361    43143988327398919500410556793212890625,
362    66408730383449729837806206197059026944,
363    74829695578286078013428929473144712489,
364    59066822915424320448445358917464096768,
365    30912680532870672635673352936887453361,
366    340039485861577398992406882305761986971,
367    100000000000000000000000000000000000000,
368    16423203268260658146231467800709255289,
369    147808829414345923316083210206383297601,
370    10633823966279326983230456482242756608,
371    85070591730234615865843651857942052864,
372    2183814375991796599109312252753832343,
373    15286700631942576193765185769276826401,
374    107006904423598033356356300384937784807,
375    623673825204293256669089197883129856,
376    3742042951225759540014535187298779136,
377    22452257707354557240087211123792674816,
378    134713546244127343440523266742756048896,
379    88817841970012523233890533447265625,
380    444089209850062616169452667236328125,
381    2220446049250313080847263336181640625,
382    11102230246251565404236316680908203125,
383    55511151231257827021181583404541015625,
384    277555756156289135105907917022705078125,
385    5192296858534827628530496329220096,
386    20769187434139310514121985316880384,
387    83076749736557242056487941267521536,
388    332306998946228968225951765070086144,
389    1329227995784915872903807060280344576,
390    5316911983139663491615228241121378304,
391    21267647932558653966460912964485513216,
392    85070591730234615865843651857942052864,
393    3433683820292512484657849089281,
394    10301051460877537453973547267843,
395    30903154382632612361920641803529,
396    92709463147897837085761925410587,
397    278128389443693511257285776231761,
398    834385168331080533771857328695283,
399    2503155504993241601315571986085849,
400    7509466514979724803946715958257547,
401    22528399544939174411840147874772641,
402    67585198634817523235520443624317923,
403    202755595904452569706561330872953769,
404    608266787713357709119683992618861307,
405    1824800363140073127359051977856583921,
406    5474401089420219382077155933569751763,
407    16423203268260658146231467800709255289,
408    49269609804781974438694403402127765867,
409    147808829414345923316083210206383297601,
410    2417851639229258349412352,
411    4835703278458516698824704,
412    9671406556917033397649408,
413    19342813113834066795298816,
414    38685626227668133590597632,
415    77371252455336267181195264,
416    154742504910672534362390528,
417    309485009821345068724781056,
418    618970019642690137449562112,
419    1237940039285380274899124224,
420    2475880078570760549798248448,
421    4951760157141521099596496896,
422    9903520314283042199192993792,
423    19807040628566084398385987584,
424    39614081257132168796771975168,
425    79228162514264337593543950336,
426    158456325028528675187087900672,
427    316912650057057350374175801344,
428    633825300114114700748351602688,
429    1267650600228229401496703205376,
430    2535301200456458802993406410752,
431    5070602400912917605986812821504,
432    10141204801825835211973625643008,
433    20282409603651670423947251286016,
434    40564819207303340847894502572032,
435    81129638414606681695789005144064,
436    162259276829213363391578010288128,
437    324518553658426726783156020576256,
438    649037107316853453566312041152512,
439    1298074214633706907132624082305024,
440    2596148429267413814265248164610048,
441    5192296858534827628530496329220096,
442    10384593717069655257060992658440192,
443    20769187434139310514121985316880384,
444    41538374868278621028243970633760768,
445    83076749736557242056487941267521536,
446    166153499473114484112975882535043072,
447    332306998946228968225951765070086144,
448    664613997892457936451903530140172288,
449    1329227995784915872903807060280344576,
450    2658455991569831745807614120560689152,
451    5316911983139663491615228241121378304,
452    10633823966279326983230456482242756608,
453    21267647932558653966460912964485513216,
454    42535295865117307932921825928971026432,
455    85070591730234615865843651857942052864,
456    170141183460469231731687303715884105728,
457];
458
459private_test_fn! {floor_root_approx_and_refine<
460    T: PrimitiveUnsigned,
461    F: Fn(T) -> f64,
462    G: Fn(f64) -> T,
463>(
464    f: F,
465    g: G,
466    x: T,
467    exp: u64,
468) -> T {
469    assert_ne!(exp, 0);
470    if x == T::ZERO || exp == 1 {
471        return x;
472    }
473    if exp >= T::WIDTH {
474        return T::ONE;
475    }
476    let exp_usize = usize::wrapping_from(exp);
477    let max_root = match T::WIDTH {
478        u8::WIDTH => T::wrapping_from(MAX_BASE_8[exp_usize]),
479        u16::WIDTH => T::wrapping_from(MAX_BASE_16[exp_usize]),
480        u32::WIDTH => T::wrapping_from(MAX_BASE_32[exp_usize]),
481        u64::WIDTH => T::wrapping_from(MAX_BASE_64[exp_usize]),
482        u128::WIDTH => T::wrapping_from(MAX_BASE_128[exp_usize]),
483        _ => unreachable!(),
484    };
485    let max_pow = match T::WIDTH {
486        u8::WIDTH => T::wrapping_from(MAX_POWER_8[exp_usize]),
487        u16::WIDTH => T::wrapping_from(MAX_POWER_16[exp_usize]),
488        u32::WIDTH => T::wrapping_from(MAX_POWER_32[exp_usize]),
489        u64::WIDTH => T::wrapping_from(MAX_POWER_64[exp_usize]),
490        u128::WIDTH => T::wrapping_from(MAX_POWER_128[exp_usize]),
491        _ => unreachable!(),
492    };
493    if x >= max_pow {
494        return max_root;
495    }
496    let mut root = g(f(x).pow(1.0 / (exp as f64)));
497    let mut pow = if let Some(pow) = root.checked_pow(exp) {
498        pow
499    } else {
500        // set to max possible pow
501        root = max_root;
502        max_pow
503    };
504    match pow.cmp(&x) {
505        Equal => root,
506        Less => loop {
507            root += T::ONE;
508            pow = root.pow(exp);
509            match pow.cmp(&x) {
510                Equal => return root,
511                Less => {}
512                Greater => return root - T::ONE,
513            }
514        },
515        Greater => loop {
516            root -= T::ONE;
517            pow = root.pow(exp);
518            if pow <= x {
519                return root;
520            }
521        },
522    }
523}}
524
525// Coefficients of Chebyshev's approximation polynomial (deg 2) {c0, c1, c2} splitting 0.5 to 1 into
526// 8 equal intervals
527//
528// Values of these coefficients of Chebyshev's approximation polynomial have been calculated from
529// the python module, "mpmath" - http://mpmath.org/ function call: mpmath.chebyfit(lambda x:
530// mpmath.root(x,3), [i, j], 3, error=True) where (i, j) is the  range.
531//
532// ```
533//          c0          c1           c2        range
534// 0.445434042 0.864136635 -0.335205926 [0.50000, 0.53125]
535// 0.454263239 0.830878907 -0.303884962 [0.53125, 0.56250]
536// 0.462761624 0.800647514 -0.276997626 [0.56250, 0.59375]
537// 0.470958569 0.773024522 -0.253724515 [0.59375, 0.62500]
538// 0.478879482 0.747667468 -0.233429710 [0.62500, 0.65625]
539// 0.486546506 0.724292830 -0.215613166 [0.65625, 0.68750]
540// 0.493979069 0.702663686 -0.199877008 [0.68750, 0.71875]
541// 0.501194325 0.682580388 -0.185901247 [0.71875, 0.75000]
542// 0.508207500 0.663873398 -0.173426009 [0.75000, 0.78125]
543// 0.515032183 0.646397742 -0.162238357 [0.78125, 0.81250]
544// 0.521680556 0.630028647 -0.152162376 [0.81250, 0.84375]
545// 0.528163588 0.614658092 -0.143051642 [0.84375, 0.87500]
546// 0.534491194 0.600192044 -0.134783425 [0.87500, 0.90625]
547// 0.540672371 0.586548233 -0.127254189 [0.90625, 0.93750]
548// 0.546715310 0.573654340 -0.120376066 [0.93750, 0.96875]
549// 0.552627494 0.561446514 -0.114074068 [0.96875, 1.00000]
550// ```
551//
552// 1^(1/3), 2^(1/3), 4^(1/3)
553const FACTOR_TABLE: [f32; 3] = [1.000000, 1.259921, 1.587401];
554
555#[allow(clippy::excessive_precision)]
556const COEFF: [[f32; 3]; 16] = [
557    [0.445434042, 0.864136635, -0.335205926],
558    [0.454263239, 0.830878907, -0.303884962],
559    [0.462761624, 0.800647514, -0.276997626],
560    [0.470958569, 0.773024522, -0.253724515],
561    [0.478879482, 0.747667468, -0.233429710],
562    [0.486546506, 0.724292830, -0.215613166],
563    [0.493979069, 0.702663686, -0.199877008],
564    [0.501194325, 0.682580388, -0.185901247],
565    [0.508207500, 0.663873398, -0.173426009],
566    [0.515032183, 0.646397742, -0.162238357],
567    [0.521680556, 0.630028647, -0.152162376],
568    [0.528163588, 0.614658092, -0.143051642],
569    [0.534491194, 0.600192044, -0.134783425],
570    [0.540672371, 0.586548233, -0.127254189],
571    [0.546715310, 0.573654340, -0.120376066],
572    [0.552627494, 0.561446514, -0.114074068],
573];
574
575// n cannot be 0
576//
577// This is equivalent to `n_cbrt_chebyshev_approx` from
578// `ulong_extras/cbrt_chebyshev_approximation.c`, FLINT 2.7.1, where `FLINT64` is `false`.
579private_test_fn! {cbrt_chebyshev_approx_u32(n: u32) -> u32 {
580    // UPPER_LIMIT is the max cube root possible for one word
581    const UPPER_LIMIT: u32 = 1625; // 1625 < (2^32)^(1/3)
582    const BIAS_HEX: u32 = 0x3f000000;
583    const BIAS: u32 = 126;
584    let (mantissa, exponent) = (n as f32).raw_mantissa_and_exponent();
585    let mut mantissa = u32::wrapping_from(mantissa);
586    let table_index = usize::wrapping_from(mantissa >> const { f32::MANTISSA_WIDTH - 4 });
587    mantissa |= BIAS_HEX;
588    let (exponent_over_3, exponent_rem) = (u32::wrapping_from(exponent) - BIAS).div_mod(3);
589
590    // Calculating cube root of dec using Chebyshev approximation polynomial
591    //
592    // Evaluating approx polynomial at (dec) by Estrin's scheme
593    let x = f32::from_bits(mantissa);
594    let row = COEFF[table_index];
595    let mut cbrt = ((row[0] + row[1] * x + row[2] * (x * x))
596        * f32::power_of_2(i64::wrapping_from(exponent_over_3))
597        * FACTOR_TABLE[usize::wrapping_from(exponent_rem)]) as u32;
598    const MAX_CUBE: u32 = UPPER_LIMIT * UPPER_LIMIT * UPPER_LIMIT;
599    if cbrt >= UPPER_LIMIT {
600        if n >= MAX_CUBE {
601            return UPPER_LIMIT;
602        }
603        cbrt = const { UPPER_LIMIT - 1 };
604    }
605    while cbrt * cbrt * cbrt <= n {
606        cbrt += 1;
607        if cbrt == UPPER_LIMIT {
608            break;
609        }
610    }
611    while cbrt * cbrt * cbrt > n {
612        cbrt -= 1;
613    }
614    cbrt
615}}
616
617// n cannot be 0
618//
619// This is equivalent to `n_cbrt_chebyshev_approx` from
620// `ulong_extras/cbrt_chebyshev_approximation.c`, FLINT 2.7.1, where `FLINT64` is `true`.
621private_test_fn! {cbrt_chebyshev_approx_u64(n: u64) -> u64 {
622    // UPPER_LIMIT is the max cube root possible for one word
623    const UPPER_LIMIT: u64 = 2642245; // 2642245 < (2^64)^(1/3)
624    const BIAS_HEX: u64 = 0x3fe0000000000000;
625    const BIAS: u64 = 1022;
626    let (mut mantissa, exponent) = (n as f64).raw_mantissa_and_exponent();
627    let table_index = usize::wrapping_from(mantissa >> const { f64::MANTISSA_WIDTH - 4 });
628    mantissa |= BIAS_HEX;
629    let (exponent_over_3, exponent_rem) = (exponent - BIAS).div_mod(3);
630
631    // Calculating cube root of dec using Chebyshev approximation polynomial
632    //
633    // Evaluating approx polynomial at x by Estrin's scheme
634    let x = f64::from_bits(mantissa);
635    let row = COEFF[table_index];
636    let mut cbrt = ((f64::from(row[0]) + f64::from(row[1]) * x + f64::from(row[2]) * (x * x))
637        * f64::power_of_2(i64::wrapping_from(exponent_over_3))
638        * f64::from(FACTOR_TABLE[usize::wrapping_from(exponent_rem)])) as u64;
639    const MAX_CUBE: u64 = UPPER_LIMIT * UPPER_LIMIT * UPPER_LIMIT;
640    if cbrt >= UPPER_LIMIT {
641        if n >= MAX_CUBE {
642            return UPPER_LIMIT;
643        }
644        cbrt = const { UPPER_LIMIT - 1 };
645    }
646    while cbrt * cbrt * cbrt <= n {
647        cbrt += 1;
648        if cbrt == UPPER_LIMIT {
649            break;
650        }
651    }
652    while cbrt * cbrt * cbrt > n {
653        cbrt -= 1;
654    }
655    cbrt
656}}
657
658// This is equivalent to `n_cbrt_estimate` from `ulong_extras/n_cbrt_estimate.c`, FLINT 2.7.1, where
659// `FLINT64` is `true`.
660#[cfg(feature = "test_build")]
661fn cbrt_estimate_f64(a: f64) -> f64 {
662    const S: u64 = 4607182418800017408; // ((1 << 10) - 1) << 52
663    f64::from_bits((u128::from(a.to_bits() - S) * 6148914691236517205).upper_half() + S)
664}
665
666// This is equivalent to `n_cbrt` from `ulong_extras/cbrt.c`, FLINT 2.7.1, where `FLINT64` is
667// `false`.
668#[cfg(feature = "test_build")]
669pub fn fast_floor_cbrt_u32(n: u32) -> u32 {
670    // Taking care of smaller roots
671    if n < 125 {
672        return if n >= 64 {
673            4
674        } else if n >= 27 {
675            3
676        } else if n >= 8 {
677            2
678        } else {
679            u32::from(n >= 1)
680        };
681    }
682    if n < 1331 {
683        return if n >= 1000 {
684            10
685        } else if n >= 729 {
686            9
687        } else if n >= 512 {
688            8
689        } else if n >= 343 {
690            7
691        } else if n >= 216 {
692            6
693        } else {
694            5
695        };
696    }
697    if n < 4913 {
698        return if n >= 4096 {
699            16
700        } else if n >= 3375 {
701            15
702        } else if n >= 2744 {
703            14
704        } else if n >= 2197 {
705            13
706        } else if n >= 1728 {
707            12
708        } else {
709            11
710        };
711    }
712    let val = f64::from(n);
713    const UPPER_LIMIT: u32 = 1625; // 1625 < (2^32)^(1/3)
714    let mut x = cbrt_estimate_f64(val);
715    // Kahan's iterations to get cube root
716    let xcub = x * x * x;
717    let num = (xcub - val) * x;
718    let den = xcub + xcub + val;
719    x -= num / den;
720    let mut ret = x as u32;
721    const UPPER_LIMIT_CUBE: u32 = UPPER_LIMIT * UPPER_LIMIT * UPPER_LIMIT;
722    // In case ret ^ 3 or (ret + 1) ^ 3 will cause overflow
723    if ret >= UPPER_LIMIT {
724        if n >= UPPER_LIMIT_CUBE {
725            return UPPER_LIMIT;
726        }
727        ret = const { UPPER_LIMIT - 1 };
728    }
729    while ret * ret * ret <= n {
730        ret += 1;
731        if ret == UPPER_LIMIT {
732            break;
733        }
734    }
735    while ret * ret * ret > n {
736        ret -= 1;
737    }
738    ret
739}
740
741// TODO tune
742#[cfg(feature = "test_build")]
743const CBRT_CHEBYSHEV_THRESHOLD: u64 = 10;
744
745// This is equivalent to `n_cbrt` from `ulong_extras/cbrt.c`, FLINT 2.7.1, where `FLINT64` is
746// `true`.
747#[cfg(feature = "test_build")]
748pub fn fast_floor_cbrt_u64(n: u64) -> u64 {
749    // Taking care of smaller roots
750    if n < 125 {
751        return if n >= 64 {
752            4
753        } else if n >= 27 {
754            3
755        } else if n >= 8 {
756            2
757        } else {
758            u64::from(n >= 1)
759        };
760    }
761    if n < 1331 {
762        return if n >= 1000 {
763            10
764        } else if n >= 729 {
765            9
766        } else if n >= 512 {
767            8
768        } else if n >= 343 {
769            7
770        } else if n >= 216 {
771            6
772        } else {
773            5
774        };
775    }
776    if n < 4913 {
777        return if n >= 4096 {
778            16
779        } else if n >= 3375 {
780            15
781        } else if n >= 2744 {
782            14
783        } else if n >= 2197 {
784            13
785        } else if n >= 1728 {
786            12
787        } else {
788            11
789        };
790    }
791    if n.significant_bits() > CBRT_CHEBYSHEV_THRESHOLD {
792        return cbrt_chebyshev_approx_u64(n);
793    }
794    let val = n as f64;
795    const UPPER_LIMIT: u64 = 2642245; // 2642245 < (2^64)^(1/3)
796    let mut x = cbrt_estimate_f64(val);
797    // Kahan's iterations to get cube root
798    let xcub = x * x * x;
799    let num = (xcub - val) * x;
800    let den = xcub + xcub + val;
801    x -= num / den;
802    let mut ret = x as u64;
803    const UPPER_LIMIT_CUBE: u64 = UPPER_LIMIT * UPPER_LIMIT * UPPER_LIMIT;
804    // In case ret ^ 3 or (ret + 1) ^ 3 will cause overflow
805    if ret >= UPPER_LIMIT {
806        if n >= UPPER_LIMIT_CUBE {
807            return UPPER_LIMIT;
808        }
809        ret = const { UPPER_LIMIT - 1 };
810    }
811    while ret * ret * ret <= n {
812        ret += 1;
813        if ret == UPPER_LIMIT {
814            break;
815        }
816    }
817    while ret * ret * ret > n {
818        ret -= 1;
819    }
820    ret
821}
822
823// this table contains the value of UWORD_MAX / n, for n in range [1, 32]
824const MUL_FACTOR_32: [u32; 33] = [
825    0,
826    u32::MAX,
827    2147483647,
828    1431655765,
829    1073741823,
830    858993459,
831    715827882,
832    613566756,
833    536870911,
834    477218588,
835    429496729,
836    390451572,
837    357913941,
838    330382099,
839    306783378,
840    286331153,
841    268435455,
842    252645135,
843    238609294,
844    226050910,
845    214748364,
846    204522252,
847    195225786,
848    186737708,
849    178956970,
850    171798691,
851    165191049,
852    159072862,
853    153391689,
854    148102320,
855    143165576,
856    138547332,
857    134217727,
858];
859
860// this table contains the value of UWORD_MAX / n, for n in range [1, 64]
861const MUL_FACTOR_64: [u64; 65] = [
862    0,
863    u64::MAX,
864    9223372036854775807,
865    6148914691236517205,
866    4611686018427387903,
867    3689348814741910323,
868    3074457345618258602,
869    2635249153387078802,
870    2305843009213693951,
871    2049638230412172401,
872    1844674407370955161,
873    1676976733973595601,
874    1537228672809129301,
875    1418980313362273201,
876    1317624576693539401,
877    1229782938247303441,
878    1152921504606846975,
879    1085102592571150095,
880    1024819115206086200,
881    970881267037344821,
882    922337203685477580,
883    878416384462359600,
884    838488366986797800,
885    802032351030850070,
886    768614336404564650,
887    737869762948382064,
888    709490156681136600,
889    683212743470724133,
890    658812288346769700,
891    636094623231363848,
892    614891469123651720,
893    595056260442243600,
894    576460752303423487,
895    558992244657865200,
896    542551296285575047,
897    527049830677415760,
898    512409557603043100,
899    498560650640798692,
900    485440633518672410,
901    472993437787424400,
902    461168601842738790,
903    449920587163647600,
904    439208192231179800,
905    428994048225803525,
906    419244183493398900,
907    409927646082434480,
908    401016175515425035,
909    392483916461905353,
910    384307168202282325,
911    376464164769582686,
912    368934881474191032,
913    361700864190383365,
914    354745078340568300,
915    348051774975651917,
916    341606371735362066,
917    335395346794719120,
918    329406144173384850,
919    323627089012448273,
920    318047311615681924,
921    312656679215416129,
922    307445734561825860,
923    302405640552615600,
924    297528130221121800,
925    292805461487453200,
926    288230376151711743,
927];
928
929// This is equivalent to `n_root_estimate` from `ulong_extras/root_estimate.c`, FLINT 2.7.1, where
930// `FLINT64` is `false`.
931fn root_estimate_32(a: f64, n: usize) -> u32 {
932    let s = u32::low_mask(const { f32::EXPONENT_WIDTH - 1 }) << f32::MANTISSA_WIDTH;
933    f32::from_bits(u32::x_mul_y_to_zz((a as f32).to_bits() - s, MUL_FACTOR_32[n]).0 + s) as u32
934}
935
936// This is equivalent to `n_root_estimate` from `ulong_extras/root_estimate.c`, FLINT 2.7.1, where
937// `FLINT64` is `true`.
938fn root_estimate_64(a: f64, n: usize) -> u64 {
939    let s = u64::low_mask(const { f64::EXPONENT_WIDTH - 1 }) << f64::MANTISSA_WIDTH;
940    f64::from_bits(u64::x_mul_y_to_zz(a.to_bits() - s, MUL_FACTOR_64[n]).0 + s) as u64
941}
942
943const INV_TABLE: [f64; 65] = [
944    0.000000000000000,
945    1.000000000000000,
946    0.500000000000000,
947    0.333333333333333,
948    0.250000000000000,
949    0.200000000000000,
950    0.166666666666667,
951    0.142857142857143,
952    0.125000000000000,
953    0.111111111111111,
954    0.100000000000000,
955    0.090909090909091,
956    0.083333333333333,
957    0.076923076923077,
958    0.071428571428571,
959    0.066666666666667,
960    0.062500000000000,
961    0.058823529411765,
962    0.055555555555556,
963    0.052631578947368,
964    0.050000000000000,
965    0.047619047619048,
966    0.045454545454545,
967    0.043478260869565,
968    0.041666666666667,
969    0.040000000000000,
970    0.038461538461538,
971    0.037037037037037,
972    0.035714285714286,
973    0.034482758620690,
974    0.033333333333333,
975    0.032258064516129,
976    0.031250000000000,
977    0.030303030303030,
978    0.029411764705882,
979    0.028571428571429,
980    0.027777777777778,
981    0.027027027027027,
982    0.026315789473684,
983    0.025641025641026,
984    0.025000000000000,
985    0.024390243902439,
986    0.023809523809524,
987    0.023255813953488,
988    0.022727272727273,
989    0.022222222222222,
990    0.021739130434783,
991    0.021276595744681,
992    0.020833333333333,
993    0.020408163265306,
994    0.020000000000000,
995    0.019607843137255,
996    0.019230769230769,
997    0.018867924528302,
998    0.018518518518519,
999    0.018181818181818,
1000    0.017857142857143,
1001    0.017543859649123,
1002    0.017241379310345,
1003    0.016949152542373,
1004    0.016666666666667,
1005    0.016393442622951,
1006    0.016129032258065,
1007    0.015873015873016,
1008    0.015625000000000,
1009];
1010
1011// This is equivalent to `n_root` from `ulong_extras/root.c`, FLINT 2.7.1, where `FLINT64` is
1012// `false` and `root` is nonzero.
1013private_test_fn! {fast_floor_root_u32(n: u32, exp: u64) -> u32 {
1014    assert_ne!(exp, 0);
1015    if n < 2 || exp == 1 {
1016        return n;
1017    } else if exp >= u32::WIDTH || n.significant_bits() <= exp {
1018        return 1;
1019    } else if exp == 2 {
1020        return n.floor_sqrt();
1021    } else if exp == 3 {
1022        return cbrt_chebyshev_approx_u32(n);
1023    }
1024    let exp = u32::wrapping_from(exp);
1025    let exp_usize = usize::wrapping_from(exp);
1026    let upper_limit = MAX_BASE_32[exp_usize]; // n <= upper_limit ^ exp
1027    let x = root_estimate_32(f64::from(n), exp_usize);
1028    // one round of Newton iteration
1029    let mut root = u32::rounding_from(
1030        (f64::from(n / x.pow(exp - 1)) - f64::from(x)) * INV_TABLE[exp_usize],
1031        Down,
1032    ).0;
1033    if root >= upper_limit {
1034        root = upper_limit - 1;
1035    }
1036    let mut pow = root.pow(exp);
1037    if pow == n {
1038        return root;
1039    }
1040    while pow <= n {
1041        root += 1;
1042        pow = root.pow(exp);
1043        if root == upper_limit {
1044            break;
1045        }
1046    }
1047    while pow > n {
1048        root -= 1;
1049        pow = root.pow(exp);
1050    }
1051    root
1052}}
1053
1054// This is equivalent to `n_root` from `ulong_extras/root.c`, FLINT 2.7.1, where `FLINT64` is `true`
1055// and `root` is nonzero.
1056private_test_fn! {fast_floor_root_u64(n: u64, exp: u64) -> u64 {
1057    assert_ne!(exp, 0);
1058    if n < 2 || exp == 1 {
1059        return n;
1060    } else if exp == 2 {
1061        return n.floor_sqrt();
1062    } else if exp == 3 {
1063        return cbrt_chebyshev_approx_u64(n);
1064    } else if exp >= u64::WIDTH || u64::power_of_2(exp) > n {
1065        return 1;
1066    }
1067    let exp = u32::wrapping_from(exp);
1068    let exp_usize = usize::wrapping_from(exp);
1069    let upper_limit = MAX_BASE_64[exp_usize]; // n <= upper_limit ^ exp
1070    let x = root_estimate_64(n as f64, exp_usize);
1071    // one round of Newton iteration
1072    let mut root = u64::rounding_from(
1073        (((n / x.saturating_pow(exp - 1)) as f64) - x as f64) * INV_TABLE[exp_usize],
1074        Down,
1075    ).0;
1076    if root >= upper_limit {
1077        root = upper_limit - 1;
1078    }
1079    let mut pow = root.pow(exp);
1080    if pow == n {
1081        return root;
1082    }
1083    while pow <= n {
1084        root += 1;
1085        pow = root.pow(exp);
1086        if root == upper_limit {
1087            break;
1088        }
1089    }
1090    while pow > n {
1091        root -= 1;
1092        pow = root.pow(exp);
1093    }
1094    root
1095}}
1096
1097private_test_fn! {fast_ceiling_root_u32(n: u32, exp: u64) -> u32 {
1098    assert_ne!(exp, 0);
1099    if n < 2 || exp == 1 {
1100        return n;
1101    }
1102    if exp >= u32::WIDTH || n.significant_bits() <= exp {
1103        return 2;
1104    }
1105    if exp == 2 {
1106        return n.ceiling_sqrt();
1107    }
1108    if exp == 3 {
1109        let root = cbrt_chebyshev_approx_u32(n);
1110        return if root.pow(3) == n { root } else { root + 1 };
1111    }
1112    let exp = u32::wrapping_from(exp);
1113    let exp_usize = usize::wrapping_from(exp);
1114    let upper_limit = MAX_BASE_32[exp_usize]; // n <= upper_limit ^ exp
1115    let x = root_estimate_32(f64::from(n), exp_usize);
1116    // one round of Newton iteration
1117    let mut root = u32::rounding_from(
1118        (f64::from(n / x.pow(exp - 1)) - f64::from(x)) * INV_TABLE[exp_usize],
1119        Down,
1120    ).0;
1121    if root >= upper_limit {
1122        root = upper_limit - 1;
1123    }
1124    let mut pow = root.pow(exp);
1125    if pow == n {
1126        return root;
1127    }
1128    while pow <= n {
1129        root += 1;
1130        pow = root.pow(exp);
1131        if root == upper_limit {
1132            break;
1133        }
1134    }
1135    while pow > n {
1136        root -= 1;
1137        pow = root.pow(exp);
1138    }
1139    if pow == n {
1140        root
1141    } else {
1142        root + 1
1143    }
1144}}
1145
1146private_test_fn! {fast_ceiling_root_u64(n: u64, exp: u64) -> u64 {
1147    assert_ne!(exp, 0);
1148    if n < 2 || exp == 1 {
1149        return n;
1150    }
1151    if exp >= u64::WIDTH || n.significant_bits() <= exp {
1152        return 2;
1153    }
1154    if exp == 2 {
1155        return n.ceiling_sqrt();
1156    }
1157    if exp == 3 {
1158        let root = cbrt_chebyshev_approx_u64(n);
1159        return if root.pow(3) == n { root } else { root + 1 };
1160    }
1161    let exp = u32::wrapping_from(exp);
1162    let exp_usize = usize::wrapping_from(exp);
1163    let upper_limit = MAX_BASE_64[exp_usize]; // n <= upper_limit ^ root
1164    let x = root_estimate_64(n as f64, exp_usize);
1165    // one round of Newton iteration
1166    let mut root = u64::rounding_from(
1167        (((n / x.wrapping_pow(exp - 1)) as f64) - x as f64) * INV_TABLE[exp_usize],
1168        Down,
1169    ).0;
1170    if root >= upper_limit {
1171        root = upper_limit - 1;
1172    }
1173    let mut pow = root.pow(exp);
1174    if pow == n {
1175        return root;
1176    }
1177    while pow <= n {
1178        root += 1;
1179        pow = root.pow(exp);
1180        if root == upper_limit {
1181            break;
1182        }
1183    }
1184    while pow > n {
1185        root -= 1;
1186        pow = root.pow(exp);
1187    }
1188    if pow == n {
1189        root
1190    } else {
1191        root + 1
1192    }
1193}}
1194
1195private_test_fn! {fast_checked_root_u32(n: u32, exp: u64) -> Option<u32> {
1196    assert_ne!(exp, 0);
1197    if n < 2 || exp == 1 {
1198        return Some(n);
1199    }
1200    if exp >= u32::WIDTH || n.significant_bits() <= exp {
1201        return None;
1202    }
1203    if exp == 2 {
1204        return n.checked_sqrt();
1205    }
1206    if exp == 3 {
1207        let root = cbrt_chebyshev_approx_u32(n);
1208        return if root.pow(3) == n { Some(root) } else { None };
1209    }
1210    let exp = u32::wrapping_from(exp);
1211    let exp_usize = usize::wrapping_from(exp);
1212    let upper_limit = MAX_BASE_32[exp_usize]; // n <= upper_limit ^ exp
1213    let x = root_estimate_32(f64::from(n), exp_usize);
1214    // one round of Newton iteration
1215    let mut root = u32::rounding_from(
1216        (f64::from(n / x.pow(exp - 1)) - f64::from(x)) * INV_TABLE[exp_usize],
1217        Down,
1218    ).0;
1219    if root >= upper_limit {
1220        root = upper_limit - 1;
1221    }
1222    let mut pow = root.pow(exp);
1223    if pow == n {
1224        return Some(root);
1225    }
1226    while pow <= n {
1227        root += 1;
1228        pow = root.pow(exp);
1229        if root == upper_limit {
1230            break;
1231        }
1232    }
1233    while pow > n {
1234        root -= 1;
1235        pow = root.pow(exp);
1236    }
1237    if pow == n {
1238        Some(root)
1239    } else {
1240        None
1241    }
1242}}
1243
1244private_test_fn! {fast_checked_root_u64(n: u64, exp: u64) -> Option<u64> {
1245    assert_ne!(exp, 0);
1246    if n < 2 || exp == 1 {
1247        return Some(n);
1248    }
1249    if exp >= u64::WIDTH || n.significant_bits() <= exp {
1250        return None;
1251    }
1252    if exp == 2 {
1253        return n.checked_sqrt();
1254    }
1255    if exp == 3 {
1256        let root = cbrt_chebyshev_approx_u64(n);
1257        return if root.pow(3) == n { Some(root) } else { None };
1258    }
1259    let exp = u32::wrapping_from(exp);
1260    let exp_usize = usize::wrapping_from(exp);
1261    let upper_limit = MAX_BASE_64[exp_usize]; // n <= upper_limit ^ root
1262    let x = root_estimate_64(n as f64, exp_usize);
1263    // one round of Newton iteration
1264    let mut root = u64::rounding_from(
1265        (((n / x.wrapping_pow(exp - 1)) as f64) - x as f64) * INV_TABLE[exp_usize],
1266        Down,
1267    ).0;
1268    if root >= upper_limit {
1269        root = upper_limit - 1;
1270    }
1271    let mut pow = root.pow(exp);
1272    if pow == n {
1273        return Some(root);
1274    }
1275    while pow <= n {
1276        root += 1;
1277        pow = root.pow(exp);
1278        if root == upper_limit {
1279            break;
1280        }
1281    }
1282    while pow > n {
1283        root -= 1;
1284        pow = root.pow(exp);
1285    }
1286    if pow == n {
1287        Some(root)
1288    } else {
1289        None
1290    }
1291}}
1292
1293private_test_fn! {fast_root_rem_u32(n: u32, exp: u64) -> (u32, u32) {
1294    assert_ne!(exp, 0);
1295    if n < 2 || exp == 1 {
1296        return (n, 0);
1297    }
1298    if exp >= u32::WIDTH || n.significant_bits() <= exp {
1299        return (1, n - 1);
1300    }
1301    if exp == 2 {
1302        return n.sqrt_rem();
1303    }
1304    if exp == 3 {
1305        let root = cbrt_chebyshev_approx_u32(n);
1306        let pow = root.pow(3);
1307        return (root, n - pow);
1308    }
1309    let exp = u32::wrapping_from(exp);
1310    let exp_usize = usize::wrapping_from(exp);
1311    let upper_limit = MAX_BASE_32[exp_usize]; // n <= upper_limit ^ exp
1312    let x = root_estimate_32(f64::from(n), exp_usize);
1313    // one round of Newton iteration
1314    let mut root = u32::rounding_from(
1315        (f64::from(n / x.pow(exp - 1)) - f64::from(x)) * INV_TABLE[exp_usize],
1316        Down,
1317    ).0;
1318    if root >= upper_limit {
1319        root = upper_limit - 1;
1320    }
1321    let mut pow = root.pow(exp);
1322    if pow == n {
1323        return (root, 0);
1324    }
1325    while pow <= n {
1326        root += 1;
1327        pow = root.pow(exp);
1328        if root == upper_limit {
1329            break;
1330        }
1331    }
1332    while pow > n {
1333        root -= 1;
1334        pow = root.pow(exp);
1335    }
1336    (root, n - pow)
1337}}
1338
1339private_test_fn! {fast_root_rem_u64(n: u64, exp: u64) -> (u64, u64) {
1340    assert_ne!(exp, 0);
1341    if n < 2 || exp == 1 {
1342        return (n, 0);
1343    }
1344    if exp >= u64::WIDTH || n.significant_bits() <= exp {
1345        return (1, n - 1);
1346    }
1347    if exp == 2 {
1348        return n.sqrt_rem();
1349    }
1350    if exp == 3 {
1351        let root = cbrt_chebyshev_approx_u64(n);
1352        let pow = root.pow(3);
1353        return (root, n - pow);
1354    }
1355    let exp = u32::wrapping_from(exp);
1356    let exp_usize = usize::wrapping_from(exp);
1357    let upper_limit = MAX_BASE_64[exp_usize]; // n <= upper_limit ^ root
1358    let x = root_estimate_64(n as f64, exp_usize);
1359    // one round of Newton iteration
1360    let mut root = u64::rounding_from(
1361        (((n / x.wrapping_pow(exp - 1)) as f64) - x as f64) * INV_TABLE[exp_usize],
1362        Down,
1363    ).0;
1364    if root >= upper_limit {
1365        root = upper_limit - 1;
1366    }
1367    let mut pow = root.pow(exp);
1368    if pow == n {
1369        return (root, 0);
1370    }
1371    while pow <= n {
1372        root += 1;
1373        pow = root.pow(exp);
1374        if root == upper_limit {
1375            break;
1376        }
1377    }
1378    while pow > n {
1379        root -= 1;
1380        pow = root.pow(exp);
1381    }
1382    (root, n - pow)
1383}}
1384
1385#[cfg(feature = "test_build")]
1386pub fn floor_root_binary<T: PrimitiveUnsigned>(x: T, exp: u64) -> T {
1387    if exp == 0 {
1388        panic!("Cannot take 0th root");
1389    } else if exp == 1 || x < T::TWO {
1390        x
1391    } else {
1392        let bits = x.significant_bits();
1393        if bits <= exp {
1394            T::ONE
1395        } else {
1396            let p = T::power_of_2(bits.div_round(exp, Ceiling).0);
1397            floor_inverse_checked_binary(|i| i.checked_pow(exp), x, p >> 1, p)
1398        }
1399    }
1400}
1401
1402#[cfg(feature = "test_build")]
1403pub fn ceiling_root_binary<T: PrimitiveUnsigned>(x: T, exp: u64) -> T {
1404    let floor_root = floor_root_binary(x, exp);
1405    if floor_root.pow(exp) == x {
1406        floor_root
1407    } else {
1408        floor_root + T::ONE
1409    }
1410}
1411
1412#[cfg(feature = "test_build")]
1413pub fn checked_root_binary<T: PrimitiveUnsigned>(x: T, exp: u64) -> Option<T> {
1414    let floor_root = floor_root_binary(x, exp);
1415    if floor_root.pow(exp) == x {
1416        Some(floor_root)
1417    } else {
1418        None
1419    }
1420}
1421
1422#[cfg(feature = "test_build")]
1423pub fn root_rem_binary<T: PrimitiveUnsigned>(x: T, exp: u64) -> (T, T) {
1424    let floor_root = floor_root_binary(x, exp);
1425    (floor_root, x - floor_root.pow(exp))
1426}
1427
1428impl FloorRoot<u64> for u8 {
1429    type Output = Self;
1430
1431    /// Returns the floor of the $n$th root of a [`u8`].
1432    ///
1433    /// $f(x, n) = \lfloor\sqrt\[n\]{x}\rfloor$.
1434    ///
1435    /// # Worst-case complexity
1436    /// Constant time and additional memory.
1437    ///
1438    /// # Panics
1439    /// Panics if `exp` is zero.
1440    ///
1441    /// # Examples
1442    /// See [here](super::root#floor_root).
1443    ///
1444    /// # Notes
1445    /// The [`u8`] implementation uses lookup tables.
1446    #[inline]
1447    fn floor_root(self, exp: u64) -> Self {
1448        match (self, exp) {
1449            (_, 0) => panic!(),
1450            (0 | 1, _) | (_, 1) => self,
1451            (_, 8..=u64::MAX) => 1,
1452            (x, 2) => x.floor_sqrt(),
1453            (x, 3) => Self::wrapping_from(match U8_CUBES.binary_search(&x) {
1454                Ok(i) => i,
1455                Err(i) => i - 1,
1456            }),
1457            (x, 4) if x < 16 => 1,
1458            (x, 4) if x < 81 => 2,
1459            (x, 5) if x < 32 => 1,
1460            (x, 5) if x < 243 => 2,
1461            (_, 4 | 5) => 3,
1462            (x, 6) if x < 64 => 1,
1463            (x, 7) if x < 128 => 1,
1464            (_, 6 | 7) => 2,
1465        }
1466    }
1467}
1468
1469impl CeilingRoot<u64> for u8 {
1470    type Output = Self;
1471
1472    /// Returns the ceiling of the $n$th root of a [`u8`].
1473    ///
1474    /// $f(x, n) = \lceil\sqrt\[n\]{x}\rceil$.
1475    ///
1476    /// # Worst-case complexity
1477    /// Constant time and additional memory.
1478    ///
1479    /// # Panics
1480    /// Panics if `exp` is zero.
1481    ///
1482    /// # Examples
1483    /// See [here](super::root#ceiling_root).
1484    ///
1485    /// # Notes
1486    /// The [`u8`] implementation uses lookup tables.
1487    fn ceiling_root(self, exp: u64) -> Self {
1488        match (self, exp) {
1489            (_, 0) => panic!(),
1490            (0 | 1, _) | (_, 1) => self,
1491            (_, 8..=u64::MAX) => 2,
1492            (x, 2) => x.ceiling_sqrt(),
1493            (x, 3) => Self::wrapping_from(match U8_CUBES.binary_search(&x) {
1494                Ok(i) | Err(i) => i,
1495            }),
1496            (x, 4) if x <= 16 => 2,
1497            (x, 4) if x <= 81 => 3,
1498            (x, 5) if x <= 32 => 2,
1499            (x, 5) if x <= 243 => 3,
1500            (_, 4 | 5) => 4,
1501            (x, 6) if x <= 64 => 2,
1502            (x, 7) if x <= 128 => 2,
1503            (_, 6 | 7) => 3,
1504        }
1505    }
1506}
1507
1508impl CheckedRoot<u64> for u8 {
1509    type Output = Self;
1510
1511    /// Returns the the $n$th root of a [`u8`], or `None` if the [`u8`] is not a perfect $n$th
1512    /// power.
1513    ///
1514    /// $$
1515    /// f(x, n) = \\begin{cases}
1516    ///     \operatorname{Some}(sqrt\[n\]{x}) & \text{if} \\quad \sqrt\[n\]{x} \in \Z, \\\\
1517    ///     \operatorname{None} & \textrm{otherwise}.
1518    /// \\end{cases}
1519    /// $$
1520    ///
1521    /// # Worst-case complexity
1522    /// Constant time and additional memory.
1523    ///
1524    /// # Panics
1525    /// Panics if `exp` is zero.
1526    ///
1527    /// # Examples
1528    /// See [here](super::root#checked_root).
1529    ///
1530    /// # Notes
1531    /// The [`u8`] implementation uses lookup tables.
1532    fn checked_root(self, exp: u64) -> Option<Self> {
1533        match (self, exp) {
1534            (_, 0) => panic!(),
1535            (0 | 1, _) | (_, 1) => Some(self),
1536            (x, 2) => x.checked_sqrt(),
1537            (x, 3) => U8_CUBES.binary_search(&x).ok().map(Self::wrapping_from),
1538            (16, 4) | (32, 5) | (64, 6) | (128, 7) => Some(2),
1539            (81, 4) | (243, 5) => Some(3),
1540            _ => None,
1541        }
1542    }
1543}
1544
1545impl RootRem<u64> for u8 {
1546    type RootOutput = Self;
1547    type RemOutput = Self;
1548
1549    /// Returns the floor of the $n$th root of a [`u8`], and the remainder (the difference between
1550    /// the [`u8`] and the $n$th power of the floor).
1551    ///
1552    /// $f(x, n) = (\lfloor\sqrt\[n\]{x}\rfloor, x - \lfloor\sqrt\[n\]{x}\rfloor^2)$.
1553    ///
1554    /// # Worst-case complexity
1555    /// Constant time and additional memory.
1556    ///
1557    /// # Panics
1558    /// Panics if `exp` is zero.
1559    ///
1560    /// # Examples
1561    /// See [here](super::root#root_rem).
1562    ///
1563    /// # Notes
1564    /// The [`u8`] implementation uses lookup tables.
1565    fn root_rem(self, exp: u64) -> (Self, Self) {
1566        match (self, exp) {
1567            (_, 0) => panic!(),
1568            (0 | 1, _) | (_, 1) => (self, 0),
1569            (x, 8..=u64::MAX) => (1, x - 1),
1570            (x, 2) => x.sqrt_rem(),
1571            (x, 3) => match U8_CUBES.binary_search(&x) {
1572                Ok(i) => (Self::wrapping_from(i), 0),
1573                Err(i) => (Self::wrapping_from(i - 1), x - U8_CUBES[i - 1]),
1574            },
1575            (x, 4) if x < 16 => (1, x - 1),
1576            (x, 4) if x < 81 => (2, x - 16),
1577            (x, 4) => (3, x - 81),
1578            (x, 5) if x < 32 => (1, x - 1),
1579            (x, 5) if x < 243 => (2, x - 32),
1580            (x, 5) => (3, x - 243),
1581            (x, 6) if x < 64 => (1, x - 1),
1582            (x, 6) => (2, x - 64),
1583            (x, 7) if x < 128 => (1, x - 1),
1584            (x, 7) => (2, x - 128),
1585        }
1586    }
1587}
1588
1589impl FloorRoot<u64> for u16 {
1590    type Output = Self;
1591
1592    /// Returns the floor of the $n$th root of a [`u16`].
1593    ///
1594    /// $f(x, n) = \lfloor\sqrt\[n\]{x}\rfloor$.
1595    ///
1596    /// # Worst-case complexity
1597    /// Constant time and additional memory.
1598    ///
1599    /// # Panics
1600    /// Panics if `exp` is zero.
1601    ///
1602    /// # Examples
1603    /// See [here](super::root#checked_root).
1604    ///
1605    /// # Notes
1606    /// The [`u16`] implementation calls the implementation for [`u32`]s.
1607    #[inline]
1608    fn floor_root(self, exp: u64) -> Self {
1609        Self::wrapping_from(u32::from(self).floor_root(exp))
1610    }
1611}
1612
1613impl CeilingRoot<u64> for u16 {
1614    type Output = Self;
1615
1616    /// Returns the ceiling of the $n$th root of a [`u16`].
1617    ///
1618    /// $f(x, n) = \lceil\sqrt\[n\]{x}\rceil$.
1619    ///
1620    /// # Worst-case complexity
1621    /// Constant time and additional memory.
1622    ///
1623    /// # Panics
1624    /// Panics if `exp` is zero.
1625    ///
1626    /// # Examples
1627    /// See [here](super::root#ceiling_root).
1628    ///
1629    /// # Notes
1630    /// The [`u16`] implementation calls the implementation for [`u32`]s.
1631    #[inline]
1632    fn ceiling_root(self, exp: u64) -> Self {
1633        Self::wrapping_from(u32::from(self).ceiling_root(exp))
1634    }
1635}
1636
1637impl CheckedRoot<u64> for u16 {
1638    type Output = Self;
1639
1640    /// Returns the the $n$th root of a [`u16`], or `None` if the [`u16`] is not a perfect $n$th
1641    /// power.
1642    ///
1643    /// $$
1644    /// f(x, n) = \\begin{cases}
1645    ///     \operatorname{Some}(sqrt\[n\]{x}) & \text{if} \\quad \sqrt\[n\]{x} \in \Z, \\\\
1646    ///     \operatorname{None} & \textrm{otherwise}.
1647    /// \\end{cases}
1648    /// $$
1649    ///
1650    /// # Worst-case complexity
1651    /// Constant time and additional memory.
1652    ///
1653    /// # Panics
1654    /// Panics if `exp` is zero.
1655    ///
1656    /// # Examples
1657    /// See [here](super::root#checked_root).
1658    ///
1659    /// # Notes
1660    /// The [`u16`] implementation calls the implementation for [`u32`]s.
1661    #[inline]
1662    fn checked_root(self, exp: u64) -> Option<Self> {
1663        u32::from(self).checked_root(exp).map(Self::wrapping_from)
1664    }
1665}
1666
1667impl RootRem<u64> for u16 {
1668    type RootOutput = Self;
1669    type RemOutput = Self;
1670
1671    /// Returns the floor of the $n$th root of a [`u16`], and the remainder (the difference between
1672    /// the [`u16`] and the $n$th power of the floor).
1673    ///
1674    /// $f(x, n) = (\lfloor\sqrt\[n\]{x}\rfloor, x - \lfloor\sqrt\[n\]{x}\rfloor^2)$.
1675    ///
1676    /// # Worst-case complexity
1677    /// Constant time and additional memory.
1678    ///
1679    /// # Panics
1680    /// Panics if `exp` is zero.
1681    ///
1682    /// # Examples
1683    /// See [here](super::root#root_rem).
1684    ///
1685    /// # Notes
1686    /// The [`u16`] implementation calls the implementation for [`u32`]s.
1687    #[inline]
1688    fn root_rem(self, exp: u64) -> (Self, Self) {
1689        let (sqrt, rem) = u32::from(self).root_rem(exp);
1690        (Self::wrapping_from(sqrt), Self::wrapping_from(rem))
1691    }
1692}
1693
1694impl FloorRoot<u64> for u32 {
1695    type Output = Self;
1696
1697    /// Returns the floor of the $n$th root of a [`u32`].
1698    ///
1699    /// $f(x, n) = \lfloor\sqrt\[n\]{x}\rfloor$.
1700    ///
1701    /// # Worst-case complexity
1702    /// Constant time and additional memory.
1703    ///
1704    /// # Panics
1705    /// Panics if `exp` is zero.
1706    ///
1707    /// # Examples
1708    /// See [here](super::root#floor_root).
1709    ///
1710    /// # Notes
1711    /// For cube roots, the [`u32`] implementation uses a piecewise Chebyshev approximation. For
1712    /// other roots, it uses Newton's method. In both implementations, the result of these
1713    /// approximations is adjusted afterwards to account for error.
1714    #[inline]
1715    fn floor_root(self, exp: u64) -> Self {
1716        fast_floor_root_u32(self, exp)
1717    }
1718}
1719
1720impl CeilingRoot<u64> for u32 {
1721    type Output = Self;
1722
1723    /// Returns the ceiling of the $n$th root of a [`u32`].
1724    ///
1725    /// $f(x, n) = \lceil\sqrt\[n\]{x}\rceil$.
1726    ///
1727    /// # Worst-case complexity
1728    /// Constant time and additional memory.
1729    ///
1730    /// # Panics
1731    /// Panics if `exp` is zero.
1732    ///
1733    /// # Examples
1734    /// See [here](super::root#ceiling_root).
1735    ///
1736    /// # Notes
1737    /// For cube roots, the [`u32`] implementation uses a piecewise Chebyshev approximation. For
1738    /// other roots, it uses Newton's method. In both implementations, the result of these
1739    /// approximations is adjusted afterwards to account for error.
1740    #[inline]
1741    fn ceiling_root(self, exp: u64) -> Self {
1742        fast_ceiling_root_u32(self, exp)
1743    }
1744}
1745
1746impl CheckedRoot<u64> for u32 {
1747    type Output = Self;
1748
1749    /// Returns the the $n$th root of a [`u32`], or `None` if the [`u32`] is not a perfect $n$th
1750    /// power.
1751    ///
1752    /// $$
1753    /// f(x, n) = \\begin{cases}
1754    ///     \operatorname{Some}(sqrt\[n\]{x}) & \text{if} \\quad \sqrt\[n\]{x} \in \Z, \\\\
1755    ///     \operatorname{None} & \textrm{otherwise}.
1756    /// \\end{cases}
1757    /// $$
1758    ///
1759    /// # Worst-case complexity
1760    /// Constant time and additional memory.
1761    ///
1762    /// # Panics
1763    /// Panics if `exp` is zero.
1764    ///
1765    /// # Examples
1766    /// See [here](super::root#checked_root).
1767    ///
1768    /// # Notes
1769    /// For cube roots, the [`u32`] implementation uses a piecewise Chebyshev approximation. For
1770    /// other roots, it uses Newton's method. In both implementations, the result of these
1771    /// approximations is adjusted afterwards to account for error.
1772    #[inline]
1773    fn checked_root(self, exp: u64) -> Option<Self> {
1774        fast_checked_root_u32(self, exp)
1775    }
1776}
1777
1778impl RootRem<u64> for u32 {
1779    type RootOutput = Self;
1780    type RemOutput = Self;
1781
1782    /// Returns the floor of the $n$th root of a [`u32`], and the remainder (the difference between
1783    /// the [`u32`] and the $n$th power of the floor).
1784    ///
1785    /// $f(x, n) = (\lfloor\sqrt\[n\]{x}\rfloor, x - \lfloor\sqrt\[n\]{x}\rfloor^2)$.
1786    ///
1787    /// # Worst-case complexity
1788    /// Constant time and additional memory.
1789    ///
1790    /// # Panics
1791    /// Panics if `exp` is zero.
1792    ///
1793    /// # Examples
1794    /// See [here](super::root#root_rem).
1795    ///
1796    /// # Notes
1797    /// For cube roots, the [`u32`] implementation uses a piecewise Chebyshev approximation. For
1798    /// other roots, it uses Newton's method. In both implementations, the result of these
1799    /// approximations is adjusted afterwards to account for error.
1800    #[inline]
1801    fn root_rem(self, exp: u64) -> (Self, Self) {
1802        fast_root_rem_u32(self, exp)
1803    }
1804}
1805
1806impl FloorRoot<Self> for u64 {
1807    type Output = Self;
1808
1809    /// Returns the floor of the $n$th root of a [`u64`].
1810    ///
1811    /// $f(x, n) = \lfloor\sqrt\[n\]{x}\rfloor$.
1812    ///
1813    /// # Worst-case complexity
1814    /// Constant time and additional memory.
1815    ///
1816    /// # Panics
1817    /// Panics if `exp` is zero.
1818    ///
1819    /// # Examples
1820    /// See [here](super::root#floor_root).
1821    ///
1822    /// # Notes
1823    /// For cube roots, the [`u64`] implementation uses a piecewise Chebyshev approximation. For
1824    /// other roots, it uses Newton's method. In both implementations, the result of these
1825    /// approximations is adjusted afterwards to account for error.
1826    #[inline]
1827    fn floor_root(self, exp: Self) -> Self {
1828        fast_floor_root_u64(self, exp)
1829    }
1830}
1831
1832impl CeilingRoot<Self> for u64 {
1833    type Output = Self;
1834
1835    /// Returns the ceiling of the $n$th root of a [`u64`].
1836    ///
1837    /// $f(x, n) = \lceil\sqrt\[n\]{x}\rceil$.
1838    ///
1839    /// # Worst-case complexity
1840    /// Constant time and additional memory.
1841    ///
1842    /// # Panics
1843    /// Panics if `exp` is zero.
1844    ///
1845    /// # Examples
1846    /// See [here](super::root#ceiling_root).
1847    ///
1848    /// # Notes
1849    /// For cube roots, the [`u64`] implementation uses a piecewise Chebyshev approximation. For
1850    /// other roots, it uses Newton's method. In both implementations, the result of these
1851    /// approximations is adjusted afterwards to account for error.
1852    #[inline]
1853    fn ceiling_root(self, exp: Self) -> Self {
1854        fast_ceiling_root_u64(self, exp)
1855    }
1856}
1857
1858impl CheckedRoot<Self> for u64 {
1859    type Output = Self;
1860
1861    /// Returns the the $n$th root of a [`u64`], or `None` if the [`u64`] is not a perfect $n$th
1862    /// power.
1863    ///
1864    /// $$
1865    /// f(x, n) = \\begin{cases}
1866    ///     \operatorname{Some}(sqrt\[n\]{x}) & \text{if} \\quad \sqrt\[n\]{x} \in \Z, \\\\
1867    ///     \operatorname{None} & \textrm{otherwise}.
1868    /// \\end{cases}
1869    /// $$
1870    ///
1871    /// # Worst-case complexity
1872    /// Constant time and additional memory.
1873    ///
1874    /// # Panics
1875    /// Panics if `exp` is zero.
1876    ///
1877    /// # Examples
1878    /// See [here](super::root#checked_root).
1879    ///
1880    /// # Notes
1881    /// For cube roots, the [`u64`] implementation uses a piecewise Chebyshev approximation. For
1882    /// other roots, it uses Newton's method. In both implementations, the result of these
1883    /// approximations is adjusted afterwards to account for error.
1884    #[inline]
1885    fn checked_root(self, exp: Self) -> Option<Self> {
1886        fast_checked_root_u64(self, exp)
1887    }
1888}
1889
1890impl RootRem<Self> for u64 {
1891    type RootOutput = Self;
1892    type RemOutput = Self;
1893
1894    /// Returns the floor of the $n$th root of a [`u64`], and the remainder (the difference between
1895    /// the [`u64`] and the $n$th power of the floor).
1896    ///
1897    /// $f(x, n) = (\lfloor\sqrt\[n\]{x}\rfloor, x - \lfloor\sqrt\[n\]{x}\rfloor^2)$.
1898    ///
1899    /// # Worst-case complexity
1900    /// Constant time and additional memory.
1901    ///
1902    /// # Panics
1903    /// Panics if `exp` is zero.
1904    ///
1905    /// # Examples
1906    /// See [here](super::root#root_rem).
1907    ///
1908    /// # Notes
1909    /// For cube roots, the [`u64`] implementation uses a piecewise Chebyshev approximation. For
1910    /// other roots, it uses Newton's method. In both implementations, the result of these
1911    /// approximations is adjusted afterwards to account for error.
1912    #[inline]
1913    fn root_rem(self, exp: Self) -> (Self, Self) {
1914        fast_root_rem_u64(self, exp)
1915    }
1916}
1917
1918impl FloorRoot<u64> for usize {
1919    type Output = Self;
1920
1921    /// Returns the floor of the $n$th root of a [`usize`].
1922    ///
1923    /// $f(x, n) = \lfloor\sqrt\[n\]{x}\rfloor$.
1924    ///
1925    /// # Worst-case complexity
1926    /// Constant time and additional memory.
1927    ///
1928    /// # Panics
1929    /// Panics if `exp` is zero.
1930    ///
1931    /// # Examples
1932    /// See [here](super::root#floor_root).
1933    ///
1934    /// # Notes
1935    /// The [`usize`] implementation calls the [`u32`] or [`u64`] implementations.
1936    #[inline]
1937    fn floor_root(self, exp: u64) -> Self {
1938        if USIZE_IS_U32 {
1939            Self::wrapping_from(u32::wrapping_from(self).floor_root(exp))
1940        } else {
1941            Self::wrapping_from(u64::wrapping_from(self).floor_root(exp))
1942        }
1943    }
1944}
1945
1946impl CeilingRoot<u64> for usize {
1947    type Output = Self;
1948
1949    /// Returns the ceiling of the $n$th root of a [`usize`].
1950    ///
1951    /// $f(x, n) = \lceil\sqrt\[n\]{x}\rceil$.
1952    ///
1953    /// # Worst-case complexity
1954    /// Constant time and additional memory.
1955    ///
1956    /// # Panics
1957    /// Panics if `exp` is zero.
1958    ///
1959    /// # Examples
1960    /// See [here](super::root#ceiling_root).
1961    ///
1962    /// # Notes
1963    /// The [`usize`] implementation calls the [`u32`] or [`u64`] implementations.
1964    #[inline]
1965    fn ceiling_root(self, exp: u64) -> Self {
1966        if USIZE_IS_U32 {
1967            Self::wrapping_from(u32::wrapping_from(self).ceiling_root(exp))
1968        } else {
1969            Self::wrapping_from(u64::wrapping_from(self).ceiling_root(exp))
1970        }
1971    }
1972}
1973
1974impl CheckedRoot<u64> for usize {
1975    type Output = Self;
1976
1977    /// Returns the the $n$th root of a [`usize`], or `None` if the [`usize`] is not a perfect $n$th
1978    /// power.
1979    ///
1980    /// $$
1981    /// f(x, n) = \\begin{cases}
1982    ///     \operatorname{Some}(sqrt\[n\]{x}) & \text{if} \\quad \sqrt\[n\]{x} \in \Z, \\\\
1983    ///     \operatorname{None} & \textrm{otherwise}.
1984    /// \\end{cases}
1985    /// $$
1986    ///
1987    /// # Worst-case complexity
1988    /// Constant time and additional memory.
1989    ///
1990    /// # Panics
1991    /// Panics if `exp` is zero.
1992    ///
1993    /// # Examples
1994    /// See [here](super::root#checked_root).
1995    ///
1996    /// # Notes
1997    /// The [`usize`] implementation calls the [`u32`] or [`u64`] implementations.
1998    #[inline]
1999    fn checked_root(self, exp: u64) -> Option<Self> {
2000        if USIZE_IS_U32 {
2001            u32::wrapping_from(self)
2002                .checked_root(exp)
2003                .map(Self::wrapping_from)
2004        } else {
2005            u64::wrapping_from(self)
2006                .checked_root(exp)
2007                .map(Self::wrapping_from)
2008        }
2009    }
2010}
2011
2012impl RootRem<u64> for usize {
2013    type RootOutput = Self;
2014    type RemOutput = Self;
2015
2016    /// Returns the floor of the $n$th root of a [`usize`], and the remainder (the difference
2017    /// between the [`usize`] and the $n$th power of the floor).
2018    ///
2019    /// $f(x, n) = (\lfloor\sqrt\[n\]{x}\rfloor, x - \lfloor\sqrt\[n\]{x}\rfloor^2)$.
2020    ///
2021    /// # Worst-case complexity
2022    /// Constant time and additional memory.
2023    ///
2024    /// # Panics
2025    /// Panics if `exp` is zero.
2026    ///
2027    /// # Examples
2028    /// See [here](super::root#root_rem).
2029    ///
2030    /// # Notes
2031    /// The [`usize`] implementation calls the [`u32`] or [`u64`] implementations.
2032    #[inline]
2033    fn root_rem(self, exp: u64) -> (Self, Self) {
2034        if USIZE_IS_U32 {
2035            let (sqrt, rem) = u32::wrapping_from(self).root_rem(exp);
2036            (Self::wrapping_from(sqrt), Self::wrapping_from(rem))
2037        } else {
2038            let (sqrt, rem) = u64::wrapping_from(self).root_rem(exp);
2039            (Self::wrapping_from(sqrt), Self::wrapping_from(rem))
2040        }
2041    }
2042}
2043
2044impl FloorRoot<u64> for u128 {
2045    type Output = Self;
2046
2047    /// Returns the floor of the $n$th root of a [`u128`].
2048    ///
2049    /// $f(x, n) = \lfloor\sqrt\[n\]{x}\rfloor$.
2050    ///
2051    /// # Worst-case complexity
2052    /// $T(n) = O(n)$
2053    ///
2054    /// $M(n) = O(1)$
2055    ///
2056    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`: constant
2057    /// for widths up to 64 bits and for exponents greater than 2, where a floating-point
2058    /// approximation is refined with $O(1)$ adjustments; 128-bit square roots (`exp == 2`) fall
2059    /// back to an $O(n)$ binary search.
2060    ///
2061    /// # Panics
2062    /// Panics if `exp` is zero.
2063    ///
2064    /// # Examples
2065    /// See [here](super::root#floor_root).
2066    ///
2067    /// # Notes
2068    /// The [`u128`] implementation computes the root using floating-point arithmetic. The
2069    /// approximate result is adjusted afterwards to account for error.
2070    fn floor_root(self, exp: u64) -> Self {
2071        if exp == 2 {
2072            return self.floor_sqrt();
2073        }
2074        floor_root_approx_and_refine(|x| x as f64, |x| x as Self, self, exp)
2075    }
2076}
2077
2078impl CeilingRoot<u64> for u128 {
2079    type Output = Self;
2080
2081    /// Returns the ceiling of the $n$th root of a [`u128`].
2082    ///
2083    /// $f(x, n) = \lceil\sqrt\[n\]{x}\rceil$.
2084    ///
2085    /// # Worst-case complexity
2086    /// $T(n) = O(n)$
2087    ///
2088    /// $M(n) = O(1)$
2089    ///
2090    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`: constant
2091    /// for widths up to 64 bits and for exponents greater than 2, where a floating-point
2092    /// approximation is refined with $O(1)$ adjustments; 128-bit square roots (`exp == 2`) fall
2093    /// back to an $O(n)$ binary search.
2094    ///
2095    /// # Panics
2096    /// Panics if `exp` is zero.
2097    ///
2098    /// # Examples
2099    /// See [here](super::root#ceiling_root).
2100    ///
2101    /// # Notes
2102    /// The [`u128`] implementation computes the root using floating-point arithmetic. The
2103    /// approximate result is adjusted afterwards to account for error.
2104    fn ceiling_root(self, exp: u64) -> Self {
2105        if exp == 2 {
2106            return self.ceiling_sqrt();
2107        }
2108        let root = floor_root_approx_and_refine(|x| x as f64, |x| x as Self, self, exp);
2109        if root.pow(u32::saturating_from(exp)) == self {
2110            root
2111        } else {
2112            root + 1
2113        }
2114    }
2115}
2116
2117impl CheckedRoot<u64> for u128 {
2118    type Output = Self;
2119
2120    /// Returns the the $n$th root of a [`u128`], or `None` if the [`u128`] is not a perfect $n$th
2121    /// power.
2122    ///
2123    /// $$
2124    /// f(x, n) = \\begin{cases}
2125    ///     \operatorname{Some}(sqrt\[n\]{x}) & \text{if} \\quad \sqrt\[n\]{x} \in \Z, \\\\
2126    ///     \operatorname{None} & \textrm{otherwise}.
2127    /// \\end{cases}
2128    /// $$
2129    ///
2130    /// # Worst-case complexity
2131    /// $T(n) = O(n)$
2132    ///
2133    /// $M(n) = O(1)$
2134    ///
2135    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`: constant
2136    /// for widths up to 64 bits and for exponents greater than 2, where a floating-point
2137    /// approximation is refined with $O(1)$ adjustments; 128-bit square roots (`exp == 2`) fall
2138    /// back to an $O(n)$ binary search.
2139    ///
2140    /// # Panics
2141    /// Panics if `exp` is zero.
2142    ///
2143    /// # Examples
2144    /// See [here](super::root#checked_root).
2145    ///
2146    /// # Notes
2147    /// The [`u128`] implementation computes the root using floating-point arithmetic. The
2148    /// approximate result is adjusted afterwards to account for error.
2149    fn checked_root(self, exp: u64) -> Option<Self> {
2150        if exp == 2 {
2151            return self.checked_sqrt();
2152        }
2153        let root = floor_root_approx_and_refine(|x| x as f64, |x| x as Self, self, exp);
2154        if root.pow(u32::saturating_from(exp)) == self {
2155            Some(root)
2156        } else {
2157            None
2158        }
2159    }
2160}
2161
2162impl RootRem<u64> for u128 {
2163    type RootOutput = Self;
2164    type RemOutput = Self;
2165
2166    /// Returns the floor of the $n$th root of a [`u128`], and the remainder (the difference between
2167    /// the [`u128`] and the $n$th power of the floor).
2168    ///
2169    /// $f(x, n) = (\lfloor\sqrt\[n\]{x}\rfloor, x - \lfloor\sqrt\[n\]{x}\rfloor^n)$.
2170    ///
2171    /// # Worst-case complexity
2172    /// $T(n) = O(n)$
2173    ///
2174    /// $M(n) = O(1)$
2175    ///
2176    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`: constant
2177    /// for widths up to 64 bits and for exponents greater than 2, where a floating-point
2178    /// approximation is refined with $O(1)$ adjustments; 128-bit square roots (`exp == 2`) fall
2179    /// back to an $O(n)$ binary search.
2180    ///
2181    /// # Panics
2182    /// Panics if `exp` is zero.
2183    ///
2184    /// # Examples
2185    /// See [here](super::root#root_rem).
2186    ///
2187    /// # Notes
2188    /// The [`u128`] implementation computes the root using floating-point arithmetic. The
2189    /// approximate result is adjusted afterwards to account for error.
2190    fn root_rem(self, exp: u64) -> (Self, Self) {
2191        if exp == 2 {
2192            return self.sqrt_rem();
2193        }
2194        let root = floor_root_approx_and_refine(|x| x as f64, |x| x as Self, self, exp);
2195        (root, self - root.pow(u32::saturating_from(exp)))
2196    }
2197}
2198
2199macro_rules! impl_root_assign_rem {
2200    ($t: ident) => {
2201        impl RootAssignRem<u64> for $t {
2202            type RemOutput = $t;
2203
2204            /// Replaces an integer with the floor of its $n$th root, and returns the remainder (the
2205            /// difference between the original integer and the $n$th power of the floor).
2206            ///
2207            /// $f(x, n) = x - \lfloor\sqrt\[n\]{x}\rfloor^n$,
2208            ///
2209            /// $x \gets \lfloor\sqrt\[n\]{x}\rfloor$.
2210            ///
2211            /// # Worst-case complexity
2212            /// $T(n) = O(n)$
2213            ///
2214            /// $M(n) = O(1)$
2215            ///
2216            /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`:
2217            /// constant for widths up to 64 bits and for exponents greater than 2, where a
2218            /// floating-point approximation is refined with $O(1)$ adjustments; 128-bit square
2219            /// roots (`exp == 2`) fall back to an $O(n)$ binary search.
2220            ///
2221            /// # Panics
2222            /// Panics if `exp` is zero.
2223            ///
2224            /// # Examples
2225            /// See [here](super::root#root_assign_rem).
2226            #[inline]
2227            fn root_assign_rem(&mut self, exp: u64) -> $t {
2228                let rem;
2229                (*self, rem) = self.root_rem(exp);
2230                rem
2231            }
2232        }
2233    };
2234}
2235apply_to_unsigneds!(impl_root_assign_rem);
2236
2237macro_rules! impl_root_signed {
2238    ($t: ident) => {
2239        impl FloorRoot<u64> for $t {
2240            type Output = $t;
2241
2242            /// Returns the floor of the $n$th root of an integer.
2243            ///
2244            /// $f(x, n) = \lfloor\sqrt\[n\]{x}\rfloor$.
2245            ///
2246            /// # Worst-case complexity
2247            /// $T(n) = O(n)$
2248            ///
2249            /// $M(n) = O(1)$
2250            ///
2251            /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`:
2252            /// constant for widths up to 64 bits and for exponents greater than 2, where a
2253            /// floating-point approximation is refined with $O(1)$ adjustments; 128-bit square
2254            /// roots (`exp == 2`) fall back to an $O(n)$ binary search.
2255            ///
2256            /// # Panics
2257            /// Panics if `exp` is zero, or if `self` is negative and `exp` is even.
2258            ///
2259            /// # Examples
2260            /// See [here](super::root#floor_root).
2261            #[inline]
2262            fn floor_root(self, exp: u64) -> $t {
2263                if self >= 0 {
2264                    $t::wrapping_from(self.unsigned_abs().floor_root(exp))
2265                } else if exp.odd() {
2266                    $t::wrapping_from(self.unsigned_abs().ceiling_root(exp)).wrapping_neg()
2267                } else {
2268                    panic!("Cannot take even root of a negative number");
2269                }
2270            }
2271        }
2272
2273        impl CeilingRoot<u64> for $t {
2274            type Output = $t;
2275
2276            /// Returns the ceiling of the $n$th root of an integer.
2277            ///
2278            /// $f(x, n) = \lceil\sqrt\[n\]{x}\rceil$.
2279            ///
2280            /// # Worst-case complexity
2281            /// $T(n) = O(n)$
2282            ///
2283            /// $M(n) = O(1)$
2284            ///
2285            /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`:
2286            /// constant for widths up to 64 bits and for exponents greater than 2, where a
2287            /// floating-point approximation is refined with $O(1)$ adjustments; 128-bit square
2288            /// roots (`exp == 2`) fall back to an $O(n)$ binary search.
2289            ///
2290            /// # Panics
2291            /// Panics if `exp` is zero, or if `self` is negative and `exp` is even.
2292            ///
2293            /// # Examples
2294            /// See [here](super::root#ceiling_root).
2295            #[inline]
2296            fn ceiling_root(self, exp: u64) -> $t {
2297                if self >= 0 {
2298                    $t::wrapping_from(self.unsigned_abs().ceiling_root(exp))
2299                } else if exp.odd() {
2300                    $t::wrapping_from(self.unsigned_abs().floor_root(exp)).wrapping_neg()
2301                } else {
2302                    panic!("Cannot take even root of a negative number");
2303                }
2304            }
2305        }
2306
2307        impl CheckedRoot<u64> for $t {
2308            type Output = $t;
2309
2310            /// Returns the the $n$th root of an integer, or `None` if the integer is not a perfect
2311            /// $n$th power.
2312            ///
2313            /// $$
2314            /// f(x, n) = \\begin{cases}
2315            ///     \operatorname{Some}(sqrt\[n\]{x}) & \text{if} \\quad \sqrt\[n\]{x} \in \Z, \\\\
2316            ///     \operatorname{None} & \textrm{otherwise}.
2317            /// \\end{cases}
2318            /// $$
2319            ///
2320            /// # Worst-case complexity
2321            /// $T(n) = O(n)$
2322            ///
2323            /// $M(n) = O(1)$
2324            ///
2325            /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`:
2326            /// constant for widths up to 64 bits and for exponents greater than 2, where a
2327            /// floating-point approximation is refined with $O(1)$ adjustments; 128-bit square
2328            /// roots (`exp == 2`) fall back to an $O(n)$ binary search.
2329            ///
2330            /// # Panics
2331            /// Panics if `exp` is zero, or if `self` is negative and `exp` is even.
2332            ///
2333            /// # Examples
2334            /// See [here](super::root#checked_root).
2335            #[inline]
2336            fn checked_root(self, exp: u64) -> Option<$t> {
2337                if self >= 0 {
2338                    self.unsigned_abs().checked_root(exp).map($t::wrapping_from)
2339                } else if exp.odd() {
2340                    self.unsigned_abs()
2341                        .checked_root(exp)
2342                        .map(|x| $t::wrapping_from(x).wrapping_neg())
2343                } else {
2344                    panic!("Cannot take even root of a negative number");
2345                }
2346            }
2347        }
2348    };
2349}
2350apply_to_signeds!(impl_root_signed);
2351
2352macro_rules! impl_root_primitive_int {
2353    ($t: ident) => {
2354        impl FloorRootAssign<u64> for $t {
2355            /// Replaces an integer with the floor of its $n$th root.
2356            ///
2357            /// $x \gets \lfloor\sqrt\[n\]{x}\rfloor$.
2358            ///
2359            /// # Worst-case complexity
2360            /// $T(n) = O(n)$
2361            ///
2362            /// $M(n) = O(1)$
2363            ///
2364            /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`:
2365            /// constant for widths up to 64 bits and for exponents greater than 2, where a
2366            /// floating-point approximation is refined with $O(1)$ adjustments; 128-bit square
2367            /// roots (`exp == 2`) fall back to an $O(n)$ binary search.
2368            ///
2369            /// # Panics
2370            /// Panics if `exp` is zero, or if `self` is negative and `exp` is even.
2371            ///
2372            /// # Examples
2373            /// See [here](super::root#floor_root_assign).
2374            #[inline]
2375            fn floor_root_assign(&mut self, exp: u64) {
2376                *self = self.floor_root(exp);
2377            }
2378        }
2379
2380        impl CeilingRootAssign<u64> for $t {
2381            /// Replaces an integer with the ceiling of its $n$th root.
2382            ///
2383            /// $x \gets \lceil\sqrt\[n\]{x}\rceil$.
2384            ///
2385            /// # Worst-case complexity
2386            /// $T(n) = O(n)$
2387            ///
2388            /// $M(n) = O(1)$
2389            ///
2390            /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`:
2391            /// constant for widths up to 64 bits and for exponents greater than 2, where a
2392            /// floating-point approximation is refined with $O(1)$ adjustments; 128-bit square
2393            /// roots (`exp == 2`) fall back to an $O(n)$ binary search.
2394            ///
2395            /// # Panics
2396            /// Panics if `exp` is zero, or if `self` is negative and `exp` is even.
2397            ///
2398            /// # Examples
2399            /// See [here](super::root#ceiling_root_assign).
2400            #[inline]
2401            fn ceiling_root_assign(&mut self, exp: u64) {
2402                *self = self.ceiling_root(exp);
2403            }
2404        }
2405    };
2406}
2407apply_to_primitive_ints!(impl_root_primitive_int);