1#[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
37const 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 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
519const 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
569pub_test! {cbrt_chebyshev_approx_u32(n: u32) -> u32 {
574 const UPPER_LIMIT: u32 = 1625; 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 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
611pub_test! {cbrt_chebyshev_approx_u64(n: u64) -> u64 {
616 const UPPER_LIMIT: u64 = 2642245; 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 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#[cfg(feature = "test_build")]
655fn cbrt_estimate_f64(a: f64) -> f64 {
656 const S: u64 = 4607182418800017408; f64::from_bits(
658 u64::wrapping_from((u128::from(a.to_bits() - S) * 6148914691236517205) >> 64) + S,
659 )
660}
661
662#[cfg(feature = "test_build")]
665pub fn fast_floor_cbrt_u32(n: u32) -> u32 {
666 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; let mut x = cbrt_estimate_f64(val);
711 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 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#[cfg(feature = "test_build")]
739const CBRT_CHEBYSHEV_THRESHOLD: u64 = 10;
740
741#[cfg(feature = "test_build")]
744pub fn fast_floor_cbrt_u64(n: u64) -> u64 {
745 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; let mut x = cbrt_estimate_f64(val);
793 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 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
819const 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
856const 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
925fn 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
932fn 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
1007pub_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]; let x = root_estimate_32(f64::from(n), exp_usize);
1024 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
1050pub_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]; let x = root_estimate_64(n as f64, exp_usize);
1067 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]; let x = root_estimate_32(f64::from(n), exp_usize);
1112 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]; let x = root_estimate_64(n as f64, exp_usize);
1161 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]; let x = root_estimate_32(f64::from(n), exp_usize);
1210 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]; let x = root_estimate_64(n as f64, exp_usize);
1259 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]; let x = root_estimate_32(f64::from(n), exp_usize);
1309 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]; let x = root_estimate_64(n as f64, exp_usize);
1355 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 #[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 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 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 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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 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 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 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 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 #[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 #[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 #[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 #[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 #[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 #[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);