malachite_base/num/arithmetic/
root.rs

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