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;
28#[cfg(feature = "test_build")]
29use crate::num::conversion::traits::SplitInHalf;
30use crate::num::conversion::traits::{
31 RawMantissaAndExponent, RoundingFrom, SaturatingFrom, WrappingFrom,
32};
33use crate::num::logic::traits::{LowMask, SignificantBits};
34use crate::rounding_modes::RoundingMode::*;
35use core::cmp::Ordering::*;
36
37const U8_CUBES: [u8; 7] = [0, 1, 8, 27, 64, 125, 216];
38
39const MAX_BASE_8: [u8; 8] = [0, 255, 15, 6, 3, 3, 2, 2];
41
42const MAX_POWER_8: [u8; 8] = [0, 255, 225, 216, 81, 243, 64, 128];
43
44const MAX_BASE_16: [u16; 16] = [0, 65535, 255, 40, 15, 9, 6, 4, 3, 3, 3, 2, 2, 2, 2, 2];
45
46const MAX_POWER_16: [u16; 16] = [
47 0, 65535, 65025, 64000, 50625, 59049, 46656, 16384, 6561, 19683, 59049, 2048, 4096, 8192,
48 16384, 32768,
49];
50
51const MAX_BASE_32: [u32; 32] = [
52 0, 4294967295, 65535, 1625, 255, 84, 40, 23, 15, 11, 9, 7, 6, 5, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2,
53 2, 2, 2, 2, 2, 2, 2, 2,
54];
55
56const MAX_POWER_32: [u32; 32] = [
57 0, 4294967295, 4294836225, 4291015625, 4228250625, 4182119424, 4096000000, 3404825447,
58 2562890625, 2357947691, 3486784401, 1977326743, 2176782336, 1220703125, 268435456, 1073741824,
59 43046721, 129140163, 387420489, 1162261467, 3486784401, 2097152, 4194304, 8388608, 16777216,
60 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824, 2147483648,
61];
62
63const MAX_BASE_64: [u64; 64] = [
64 0,
65 18446744073709551615,
66 4294967295,
67 2642245,
68 65535,
69 7131,
70 1625,
71 565,
72 255,
73 138,
74 84,
75 56,
76 40,
77 30,
78 23,
79 19,
80 15,
81 13,
82 11,
83 10,
84 9,
85 8,
86 7,
87 6,
88 6,
89 5,
90 5,
91 5,
92 4,
93 4,
94 4,
95 4,
96 3,
97 3,
98 3,
99 3,
100 3,
101 3,
102 3,
103 3,
104 3,
105 2,
106 2,
107 2,
108 2,
109 2,
110 2,
111 2,
112 2,
113 2,
114 2,
115 2,
116 2,
117 2,
118 2,
119 2,
120 2,
121 2,
122 2,
123 2,
124 2,
125 2,
126 2,
127 2,
128];
129
130const MAX_POWER_64: [u64; 64] = [
131 0,
132 18446744073709551615,
133 18446744065119617025,
134 18446724184312856125,
135 18445618199572250625,
136 18439629140666724651,
137 18412815093994140625,
138 18379730316001328125,
139 17878103347812890625,
140 18151468971815029248,
141 17490122876598091776,
142 16985107389382393856,
143 16777216000000000000,
144 15943230000000000000,
145 11592836324538749809,
146 15181127029874798299,
147 6568408355712890625,
148 8650415919381337933,
149 5559917313492231481,
150 10000000000000000000,
151 12157665459056928801,
152 9223372036854775808,
153 3909821048582988049,
154 789730223053602816,
155 4738381338321616896,
156 298023223876953125,
157 1490116119384765625,
158 7450580596923828125,
159 72057594037927936,
160 288230376151711744,
161 1152921504606846976,
162 4611686018427387904,
163 1853020188851841,
164 5559060566555523,
165 16677181699666569,
166 50031545098999707,
167 150094635296999121,
168 450283905890997363,
169 1350851717672992089,
170 4052555153018976267,
171 12157665459056928801,
172 2199023255552,
173 4398046511104,
174 8796093022208,
175 17592186044416,
176 35184372088832,
177 70368744177664,
178 140737488355328,
179 281474976710656,
180 562949953421312,
181 1125899906842624,
182 2251799813685248,
183 4503599627370496,
184 9007199254740992,
185 18014398509481984,
186 36028797018963968,
187 72057594037927936,
188 144115188075855872,
189 288230376151711744,
190 576460752303423488,
191 1152921504606846976,
192 2305843009213693952,
193 4611686018427387904,
194 9223372036854775808,
195];
196
197const MAX_BASE_128: [u128; 128] = [
198 0,
199 340282366920938463463374607431768211455,
200 18446744073709551615,
201 6981463658331,
202 4294967295,
203 50859008,
204 2642245,
205 319557,
206 65535,
207 19112,
208 7131,
209 3183,
210 1625,
211 920,
212 565,
213 370,
214 255,
215 184,
216 138,
217 106,
218 84,
219 68,
220 56,
221 47,
222 40,
223 34,
224 30,
225 26,
226 23,
227 21,
228 19,
229 17,
230 15,
231 14,
232 13,
233 12,
234 11,
235 11,
236 10,
237 9,
238 9,
239 8,
240 8,
241 7,
242 7,
243 7,
244 6,
245 6,
246 6,
247 6,
248 5,
249 5,
250 5,
251 5,
252 5,
253 5,
254 4,
255 4,
256 4,
257 4,
258 4,
259 4,
260 4,
261 4,
262 3,
263 3,
264 3,
265 3,
266 3,
267 3,
268 3,
269 3,
270 3,
271 3,
272 3,
273 3,
274 3,
275 3,
276 3,
277 3,
278 3,
279 2,
280 2,
281 2,
282 2,
283 2,
284 2,
285 2,
286 2,
287 2,
288 2,
289 2,
290 2,
291 2,
292 2,
293 2,
294 2,
295 2,
296 2,
297 2,
298 2,
299 2,
300 2,
301 2,
302 2,
303 2,
304 2,
305 2,
306 2,
307 2,
308 2,
309 2,
310 2,
311 2,
312 2,
313 2,
314 2,
315 2,
316 2,
317 2,
318 2,
319 2,
320 2,
321 2,
322 2,
323 2,
324 2,
325 2,
326];
327
328const MAX_POWER_128: [u128; 128] = [
329 0,
330 340282366920938463463374607431768211455,
331 340282366920938463426481119284349108225,
332 340282366920856711588743492508790678691,
333 340282366604025813516997721482669850625,
334 340282351457171161640582485552312352768,
335 340281633132112807150397932954950015625,
336 340281506971235808117106851925354131693,
337 340240830764391036687105719527812890625,
338 340216388952569572744243119867142602752,
339 340019922845325450206316382040251071801,
340 339784078391451014674643196649809097167,
341 339031759685618453659117221832275390625,
342 338253076642491662461829120000000000000,
343 337814486488938281014651876763916015625,
344 333446267951815307088493000000000000000,
345 319626579315078487616775634918212890625,
346 317616452802997733092688724349413228544,
347 329475825834763755052723200291095445504,
348 302559950208758936970093677790372560896,
349 305904398238499908683087849324518834176,
350 303869538891536196286006028740295917568,
351 288493873028852398739253829029106548736,
352 287243845682065590744605010781602099023,
353 281474976710656000000000000000000000000,
354 193630125104980427932766033374162714624,
355 254186582832900000000000000000000000000,
356 160059109085386090080713531498405298176,
357 134393854047545109686936775588697536481,
358 220983347100817338120002444455525554981,
359 230466617897195215045509519405933293401,
360 139288917338851014461418017489467720433,
361 43143988327398919500410556793212890625,
362 66408730383449729837806206197059026944,
363 74829695578286078013428929473144712489,
364 59066822915424320448445358917464096768,
365 30912680532870672635673352936887453361,
366 340039485861577398992406882305761986971,
367 100000000000000000000000000000000000000,
368 16423203268260658146231467800709255289,
369 147808829414345923316083210206383297601,
370 10633823966279326983230456482242756608,
371 85070591730234615865843651857942052864,
372 2183814375991796599109312252753832343,
373 15286700631942576193765185769276826401,
374 107006904423598033356356300384937784807,
375 623673825204293256669089197883129856,
376 3742042951225759540014535187298779136,
377 22452257707354557240087211123792674816,
378 134713546244127343440523266742756048896,
379 88817841970012523233890533447265625,
380 444089209850062616169452667236328125,
381 2220446049250313080847263336181640625,
382 11102230246251565404236316680908203125,
383 55511151231257827021181583404541015625,
384 277555756156289135105907917022705078125,
385 5192296858534827628530496329220096,
386 20769187434139310514121985316880384,
387 83076749736557242056487941267521536,
388 332306998946228968225951765070086144,
389 1329227995784915872903807060280344576,
390 5316911983139663491615228241121378304,
391 21267647932558653966460912964485513216,
392 85070591730234615865843651857942052864,
393 3433683820292512484657849089281,
394 10301051460877537453973547267843,
395 30903154382632612361920641803529,
396 92709463147897837085761925410587,
397 278128389443693511257285776231761,
398 834385168331080533771857328695283,
399 2503155504993241601315571986085849,
400 7509466514979724803946715958257547,
401 22528399544939174411840147874772641,
402 67585198634817523235520443624317923,
403 202755595904452569706561330872953769,
404 608266787713357709119683992618861307,
405 1824800363140073127359051977856583921,
406 5474401089420219382077155933569751763,
407 16423203268260658146231467800709255289,
408 49269609804781974438694403402127765867,
409 147808829414345923316083210206383297601,
410 2417851639229258349412352,
411 4835703278458516698824704,
412 9671406556917033397649408,
413 19342813113834066795298816,
414 38685626227668133590597632,
415 77371252455336267181195264,
416 154742504910672534362390528,
417 309485009821345068724781056,
418 618970019642690137449562112,
419 1237940039285380274899124224,
420 2475880078570760549798248448,
421 4951760157141521099596496896,
422 9903520314283042199192993792,
423 19807040628566084398385987584,
424 39614081257132168796771975168,
425 79228162514264337593543950336,
426 158456325028528675187087900672,
427 316912650057057350374175801344,
428 633825300114114700748351602688,
429 1267650600228229401496703205376,
430 2535301200456458802993406410752,
431 5070602400912917605986812821504,
432 10141204801825835211973625643008,
433 20282409603651670423947251286016,
434 40564819207303340847894502572032,
435 81129638414606681695789005144064,
436 162259276829213363391578010288128,
437 324518553658426726783156020576256,
438 649037107316853453566312041152512,
439 1298074214633706907132624082305024,
440 2596148429267413814265248164610048,
441 5192296858534827628530496329220096,
442 10384593717069655257060992658440192,
443 20769187434139310514121985316880384,
444 41538374868278621028243970633760768,
445 83076749736557242056487941267521536,
446 166153499473114484112975882535043072,
447 332306998946228968225951765070086144,
448 664613997892457936451903530140172288,
449 1329227995784915872903807060280344576,
450 2658455991569831745807614120560689152,
451 5316911983139663491615228241121378304,
452 10633823966279326983230456482242756608,
453 21267647932558653966460912964485513216,
454 42535295865117307932921825928971026432,
455 85070591730234615865843651857942052864,
456 170141183460469231731687303715884105728,
457];
458
459private_test_fn! {floor_root_approx_and_refine<
460 T: PrimitiveUnsigned,
461 F: Fn(T) -> f64,
462 G: Fn(f64) -> T,
463>(
464 f: F,
465 g: G,
466 x: T,
467 exp: u64,
468) -> T {
469 assert_ne!(exp, 0);
470 if x == T::ZERO || exp == 1 {
471 return x;
472 }
473 if exp >= T::WIDTH {
474 return T::ONE;
475 }
476 let exp_usize = usize::wrapping_from(exp);
477 let max_root = match T::WIDTH {
478 u8::WIDTH => T::wrapping_from(MAX_BASE_8[exp_usize]),
479 u16::WIDTH => T::wrapping_from(MAX_BASE_16[exp_usize]),
480 u32::WIDTH => T::wrapping_from(MAX_BASE_32[exp_usize]),
481 u64::WIDTH => T::wrapping_from(MAX_BASE_64[exp_usize]),
482 u128::WIDTH => T::wrapping_from(MAX_BASE_128[exp_usize]),
483 _ => unreachable!(),
484 };
485 let max_pow = match T::WIDTH {
486 u8::WIDTH => T::wrapping_from(MAX_POWER_8[exp_usize]),
487 u16::WIDTH => T::wrapping_from(MAX_POWER_16[exp_usize]),
488 u32::WIDTH => T::wrapping_from(MAX_POWER_32[exp_usize]),
489 u64::WIDTH => T::wrapping_from(MAX_POWER_64[exp_usize]),
490 u128::WIDTH => T::wrapping_from(MAX_POWER_128[exp_usize]),
491 _ => unreachable!(),
492 };
493 if x >= max_pow {
494 return max_root;
495 }
496 let mut root = g(f(x).pow(1.0 / (exp as f64)));
497 let mut pow = if let Some(pow) = root.checked_pow(exp) {
498 pow
499 } else {
500 root = max_root;
502 max_pow
503 };
504 match pow.cmp(&x) {
505 Equal => root,
506 Less => loop {
507 root += T::ONE;
508 pow = root.pow(exp);
509 match pow.cmp(&x) {
510 Equal => return root,
511 Less => {}
512 Greater => return root - T::ONE,
513 }
514 },
515 Greater => loop {
516 root -= T::ONE;
517 pow = root.pow(exp);
518 if pow <= x {
519 return root;
520 }
521 },
522 }
523}}
524
525const FACTOR_TABLE: [f32; 3] = [1.000000, 1.259921, 1.587401];
554
555#[allow(clippy::excessive_precision)]
556const COEFF: [[f32; 3]; 16] = [
557 [0.445434042, 0.864136635, -0.335205926],
558 [0.454263239, 0.830878907, -0.303884962],
559 [0.462761624, 0.800647514, -0.276997626],
560 [0.470958569, 0.773024522, -0.253724515],
561 [0.478879482, 0.747667468, -0.233429710],
562 [0.486546506, 0.724292830, -0.215613166],
563 [0.493979069, 0.702663686, -0.199877008],
564 [0.501194325, 0.682580388, -0.185901247],
565 [0.508207500, 0.663873398, -0.173426009],
566 [0.515032183, 0.646397742, -0.162238357],
567 [0.521680556, 0.630028647, -0.152162376],
568 [0.528163588, 0.614658092, -0.143051642],
569 [0.534491194, 0.600192044, -0.134783425],
570 [0.540672371, 0.586548233, -0.127254189],
571 [0.546715310, 0.573654340, -0.120376066],
572 [0.552627494, 0.561446514, -0.114074068],
573];
574
575private_test_fn! {cbrt_chebyshev_approx_u32(n: u32) -> u32 {
580 const UPPER_LIMIT: u32 = 1625; const BIAS_HEX: u32 = 0x3f000000;
583 const BIAS: u32 = 126;
584 let (mantissa, exponent) = (n as f32).raw_mantissa_and_exponent();
585 let mut mantissa = u32::wrapping_from(mantissa);
586 let table_index = usize::wrapping_from(mantissa >> const { f32::MANTISSA_WIDTH - 4 });
587 mantissa |= BIAS_HEX;
588 let (exponent_over_3, exponent_rem) = (u32::wrapping_from(exponent) - BIAS).div_mod(3);
589
590 let x = f32::from_bits(mantissa);
594 let row = COEFF[table_index];
595 let mut cbrt = ((row[0] + row[1] * x + row[2] * (x * x))
596 * f32::power_of_2(i64::wrapping_from(exponent_over_3))
597 * FACTOR_TABLE[usize::wrapping_from(exponent_rem)]) as u32;
598 const MAX_CUBE: u32 = UPPER_LIMIT * UPPER_LIMIT * UPPER_LIMIT;
599 if cbrt >= UPPER_LIMIT {
600 if n >= MAX_CUBE {
601 return UPPER_LIMIT;
602 }
603 cbrt = const { UPPER_LIMIT - 1 };
604 }
605 while cbrt * cbrt * cbrt <= n {
606 cbrt += 1;
607 if cbrt == UPPER_LIMIT {
608 break;
609 }
610 }
611 while cbrt * cbrt * cbrt > n {
612 cbrt -= 1;
613 }
614 cbrt
615}}
616
617private_test_fn! {cbrt_chebyshev_approx_u64(n: u64) -> u64 {
622 const UPPER_LIMIT: u64 = 2642245; const BIAS_HEX: u64 = 0x3fe0000000000000;
625 const BIAS: u64 = 1022;
626 let (mut mantissa, exponent) = (n as f64).raw_mantissa_and_exponent();
627 let table_index = usize::wrapping_from(mantissa >> const { f64::MANTISSA_WIDTH - 4 });
628 mantissa |= BIAS_HEX;
629 let (exponent_over_3, exponent_rem) = (exponent - BIAS).div_mod(3);
630
631 let x = f64::from_bits(mantissa);
635 let row = COEFF[table_index];
636 let mut cbrt = ((f64::from(row[0]) + f64::from(row[1]) * x + f64::from(row[2]) * (x * x))
637 * f64::power_of_2(i64::wrapping_from(exponent_over_3))
638 * f64::from(FACTOR_TABLE[usize::wrapping_from(exponent_rem)])) as u64;
639 const MAX_CUBE: u64 = UPPER_LIMIT * UPPER_LIMIT * UPPER_LIMIT;
640 if cbrt >= UPPER_LIMIT {
641 if n >= MAX_CUBE {
642 return UPPER_LIMIT;
643 }
644 cbrt = const { UPPER_LIMIT - 1 };
645 }
646 while cbrt * cbrt * cbrt <= n {
647 cbrt += 1;
648 if cbrt == UPPER_LIMIT {
649 break;
650 }
651 }
652 while cbrt * cbrt * cbrt > n {
653 cbrt -= 1;
654 }
655 cbrt
656}}
657
658#[cfg(feature = "test_build")]
661fn cbrt_estimate_f64(a: f64) -> f64 {
662 const S: u64 = 4607182418800017408; f64::from_bits((u128::from(a.to_bits() - S) * 6148914691236517205).upper_half() + S)
664}
665
666#[cfg(feature = "test_build")]
669pub fn fast_floor_cbrt_u32(n: u32) -> u32 {
670 if n < 125 {
672 return if n >= 64 {
673 4
674 } else if n >= 27 {
675 3
676 } else if n >= 8 {
677 2
678 } else {
679 u32::from(n >= 1)
680 };
681 }
682 if n < 1331 {
683 return if n >= 1000 {
684 10
685 } else if n >= 729 {
686 9
687 } else if n >= 512 {
688 8
689 } else if n >= 343 {
690 7
691 } else if n >= 216 {
692 6
693 } else {
694 5
695 };
696 }
697 if n < 4913 {
698 return if n >= 4096 {
699 16
700 } else if n >= 3375 {
701 15
702 } else if n >= 2744 {
703 14
704 } else if n >= 2197 {
705 13
706 } else if n >= 1728 {
707 12
708 } else {
709 11
710 };
711 }
712 let val = f64::from(n);
713 const UPPER_LIMIT: u32 = 1625; let mut x = cbrt_estimate_f64(val);
715 let xcub = x * x * x;
717 let num = (xcub - val) * x;
718 let den = xcub + xcub + val;
719 x -= num / den;
720 let mut ret = x as u32;
721 const UPPER_LIMIT_CUBE: u32 = UPPER_LIMIT * UPPER_LIMIT * UPPER_LIMIT;
722 if ret >= UPPER_LIMIT {
724 if n >= UPPER_LIMIT_CUBE {
725 return UPPER_LIMIT;
726 }
727 ret = const { UPPER_LIMIT - 1 };
728 }
729 while ret * ret * ret <= n {
730 ret += 1;
731 if ret == UPPER_LIMIT {
732 break;
733 }
734 }
735 while ret * ret * ret > n {
736 ret -= 1;
737 }
738 ret
739}
740
741#[cfg(feature = "test_build")]
743const CBRT_CHEBYSHEV_THRESHOLD: u64 = 10;
744
745#[cfg(feature = "test_build")]
748pub fn fast_floor_cbrt_u64(n: u64) -> u64 {
749 if n < 125 {
751 return if n >= 64 {
752 4
753 } else if n >= 27 {
754 3
755 } else if n >= 8 {
756 2
757 } else {
758 u64::from(n >= 1)
759 };
760 }
761 if n < 1331 {
762 return if n >= 1000 {
763 10
764 } else if n >= 729 {
765 9
766 } else if n >= 512 {
767 8
768 } else if n >= 343 {
769 7
770 } else if n >= 216 {
771 6
772 } else {
773 5
774 };
775 }
776 if n < 4913 {
777 return if n >= 4096 {
778 16
779 } else if n >= 3375 {
780 15
781 } else if n >= 2744 {
782 14
783 } else if n >= 2197 {
784 13
785 } else if n >= 1728 {
786 12
787 } else {
788 11
789 };
790 }
791 if n.significant_bits() > CBRT_CHEBYSHEV_THRESHOLD {
792 return cbrt_chebyshev_approx_u64(n);
793 }
794 let val = n as f64;
795 const UPPER_LIMIT: u64 = 2642245; let mut x = cbrt_estimate_f64(val);
797 let xcub = x * x * x;
799 let num = (xcub - val) * x;
800 let den = xcub + xcub + val;
801 x -= num / den;
802 let mut ret = x as u64;
803 const UPPER_LIMIT_CUBE: u64 = UPPER_LIMIT * UPPER_LIMIT * UPPER_LIMIT;
804 if ret >= UPPER_LIMIT {
806 if n >= UPPER_LIMIT_CUBE {
807 return UPPER_LIMIT;
808 }
809 ret = const { UPPER_LIMIT - 1 };
810 }
811 while ret * ret * ret <= n {
812 ret += 1;
813 if ret == UPPER_LIMIT {
814 break;
815 }
816 }
817 while ret * ret * ret > n {
818 ret -= 1;
819 }
820 ret
821}
822
823const MUL_FACTOR_32: [u32; 33] = [
825 0,
826 u32::MAX,
827 2147483647,
828 1431655765,
829 1073741823,
830 858993459,
831 715827882,
832 613566756,
833 536870911,
834 477218588,
835 429496729,
836 390451572,
837 357913941,
838 330382099,
839 306783378,
840 286331153,
841 268435455,
842 252645135,
843 238609294,
844 226050910,
845 214748364,
846 204522252,
847 195225786,
848 186737708,
849 178956970,
850 171798691,
851 165191049,
852 159072862,
853 153391689,
854 148102320,
855 143165576,
856 138547332,
857 134217727,
858];
859
860const MUL_FACTOR_64: [u64; 65] = [
862 0,
863 u64::MAX,
864 9223372036854775807,
865 6148914691236517205,
866 4611686018427387903,
867 3689348814741910323,
868 3074457345618258602,
869 2635249153387078802,
870 2305843009213693951,
871 2049638230412172401,
872 1844674407370955161,
873 1676976733973595601,
874 1537228672809129301,
875 1418980313362273201,
876 1317624576693539401,
877 1229782938247303441,
878 1152921504606846975,
879 1085102592571150095,
880 1024819115206086200,
881 970881267037344821,
882 922337203685477580,
883 878416384462359600,
884 838488366986797800,
885 802032351030850070,
886 768614336404564650,
887 737869762948382064,
888 709490156681136600,
889 683212743470724133,
890 658812288346769700,
891 636094623231363848,
892 614891469123651720,
893 595056260442243600,
894 576460752303423487,
895 558992244657865200,
896 542551296285575047,
897 527049830677415760,
898 512409557603043100,
899 498560650640798692,
900 485440633518672410,
901 472993437787424400,
902 461168601842738790,
903 449920587163647600,
904 439208192231179800,
905 428994048225803525,
906 419244183493398900,
907 409927646082434480,
908 401016175515425035,
909 392483916461905353,
910 384307168202282325,
911 376464164769582686,
912 368934881474191032,
913 361700864190383365,
914 354745078340568300,
915 348051774975651917,
916 341606371735362066,
917 335395346794719120,
918 329406144173384850,
919 323627089012448273,
920 318047311615681924,
921 312656679215416129,
922 307445734561825860,
923 302405640552615600,
924 297528130221121800,
925 292805461487453200,
926 288230376151711743,
927];
928
929fn root_estimate_32(a: f64, n: usize) -> u32 {
932 let s = u32::low_mask(const { f32::EXPONENT_WIDTH - 1 }) << f32::MANTISSA_WIDTH;
933 f32::from_bits(u32::x_mul_y_to_zz((a as f32).to_bits() - s, MUL_FACTOR_32[n]).0 + s) as u32
934}
935
936fn root_estimate_64(a: f64, n: usize) -> u64 {
939 let s = u64::low_mask(const { f64::EXPONENT_WIDTH - 1 }) << f64::MANTISSA_WIDTH;
940 f64::from_bits(u64::x_mul_y_to_zz(a.to_bits() - s, MUL_FACTOR_64[n]).0 + s) as u64
941}
942
943const INV_TABLE: [f64; 65] = [
944 0.000000000000000,
945 1.000000000000000,
946 0.500000000000000,
947 0.333333333333333,
948 0.250000000000000,
949 0.200000000000000,
950 0.166666666666667,
951 0.142857142857143,
952 0.125000000000000,
953 0.111111111111111,
954 0.100000000000000,
955 0.090909090909091,
956 0.083333333333333,
957 0.076923076923077,
958 0.071428571428571,
959 0.066666666666667,
960 0.062500000000000,
961 0.058823529411765,
962 0.055555555555556,
963 0.052631578947368,
964 0.050000000000000,
965 0.047619047619048,
966 0.045454545454545,
967 0.043478260869565,
968 0.041666666666667,
969 0.040000000000000,
970 0.038461538461538,
971 0.037037037037037,
972 0.035714285714286,
973 0.034482758620690,
974 0.033333333333333,
975 0.032258064516129,
976 0.031250000000000,
977 0.030303030303030,
978 0.029411764705882,
979 0.028571428571429,
980 0.027777777777778,
981 0.027027027027027,
982 0.026315789473684,
983 0.025641025641026,
984 0.025000000000000,
985 0.024390243902439,
986 0.023809523809524,
987 0.023255813953488,
988 0.022727272727273,
989 0.022222222222222,
990 0.021739130434783,
991 0.021276595744681,
992 0.020833333333333,
993 0.020408163265306,
994 0.020000000000000,
995 0.019607843137255,
996 0.019230769230769,
997 0.018867924528302,
998 0.018518518518519,
999 0.018181818181818,
1000 0.017857142857143,
1001 0.017543859649123,
1002 0.017241379310345,
1003 0.016949152542373,
1004 0.016666666666667,
1005 0.016393442622951,
1006 0.016129032258065,
1007 0.015873015873016,
1008 0.015625000000000,
1009];
1010
1011private_test_fn! {fast_floor_root_u32(n: u32, exp: u64) -> u32 {
1014 assert_ne!(exp, 0);
1015 if n < 2 || exp == 1 {
1016 return n;
1017 } else if exp >= u32::WIDTH || n.significant_bits() <= exp {
1018 return 1;
1019 } else if exp == 2 {
1020 return n.floor_sqrt();
1021 } else if exp == 3 {
1022 return cbrt_chebyshev_approx_u32(n);
1023 }
1024 let exp = u32::wrapping_from(exp);
1025 let exp_usize = usize::wrapping_from(exp);
1026 let upper_limit = MAX_BASE_32[exp_usize]; let x = root_estimate_32(f64::from(n), exp_usize);
1028 let mut root = u32::rounding_from(
1030 (f64::from(n / x.pow(exp - 1)) - f64::from(x)) * INV_TABLE[exp_usize],
1031 Down,
1032 ).0;
1033 if root >= upper_limit {
1034 root = upper_limit - 1;
1035 }
1036 let mut pow = root.pow(exp);
1037 if pow == n {
1038 return root;
1039 }
1040 while pow <= n {
1041 root += 1;
1042 pow = root.pow(exp);
1043 if root == upper_limit {
1044 break;
1045 }
1046 }
1047 while pow > n {
1048 root -= 1;
1049 pow = root.pow(exp);
1050 }
1051 root
1052}}
1053
1054private_test_fn! {fast_floor_root_u64(n: u64, exp: u64) -> u64 {
1057 assert_ne!(exp, 0);
1058 if n < 2 || exp == 1 {
1059 return n;
1060 } else if exp == 2 {
1061 return n.floor_sqrt();
1062 } else if exp == 3 {
1063 return cbrt_chebyshev_approx_u64(n);
1064 } else if exp >= u64::WIDTH || u64::power_of_2(exp) > n {
1065 return 1;
1066 }
1067 let exp = u32::wrapping_from(exp);
1068 let exp_usize = usize::wrapping_from(exp);
1069 let upper_limit = MAX_BASE_64[exp_usize]; let x = root_estimate_64(n as f64, exp_usize);
1071 let mut root = u64::rounding_from(
1073 (((n / x.saturating_pow(exp - 1)) as f64) - x as f64) * INV_TABLE[exp_usize],
1074 Down,
1075 ).0;
1076 if root >= upper_limit {
1077 root = upper_limit - 1;
1078 }
1079 let mut pow = root.pow(exp);
1080 if pow == n {
1081 return root;
1082 }
1083 while pow <= n {
1084 root += 1;
1085 pow = root.pow(exp);
1086 if root == upper_limit {
1087 break;
1088 }
1089 }
1090 while pow > n {
1091 root -= 1;
1092 pow = root.pow(exp);
1093 }
1094 root
1095}}
1096
1097private_test_fn! {fast_ceiling_root_u32(n: u32, exp: u64) -> u32 {
1098 assert_ne!(exp, 0);
1099 if n < 2 || exp == 1 {
1100 return n;
1101 }
1102 if exp >= u32::WIDTH || n.significant_bits() <= exp {
1103 return 2;
1104 }
1105 if exp == 2 {
1106 return n.ceiling_sqrt();
1107 }
1108 if exp == 3 {
1109 let root = cbrt_chebyshev_approx_u32(n);
1110 return if root.pow(3) == n { root } else { root + 1 };
1111 }
1112 let exp = u32::wrapping_from(exp);
1113 let exp_usize = usize::wrapping_from(exp);
1114 let upper_limit = MAX_BASE_32[exp_usize]; let x = root_estimate_32(f64::from(n), exp_usize);
1116 let mut root = u32::rounding_from(
1118 (f64::from(n / x.pow(exp - 1)) - f64::from(x)) * INV_TABLE[exp_usize],
1119 Down,
1120 ).0;
1121 if root >= upper_limit {
1122 root = upper_limit - 1;
1123 }
1124 let mut pow = root.pow(exp);
1125 if pow == n {
1126 return root;
1127 }
1128 while pow <= n {
1129 root += 1;
1130 pow = root.pow(exp);
1131 if root == upper_limit {
1132 break;
1133 }
1134 }
1135 while pow > n {
1136 root -= 1;
1137 pow = root.pow(exp);
1138 }
1139 if pow == n {
1140 root
1141 } else {
1142 root + 1
1143 }
1144}}
1145
1146private_test_fn! {fast_ceiling_root_u64(n: u64, exp: u64) -> u64 {
1147 assert_ne!(exp, 0);
1148 if n < 2 || exp == 1 {
1149 return n;
1150 }
1151 if exp >= u64::WIDTH || n.significant_bits() <= exp {
1152 return 2;
1153 }
1154 if exp == 2 {
1155 return n.ceiling_sqrt();
1156 }
1157 if exp == 3 {
1158 let root = cbrt_chebyshev_approx_u64(n);
1159 return if root.pow(3) == n { root } else { root + 1 };
1160 }
1161 let exp = u32::wrapping_from(exp);
1162 let exp_usize = usize::wrapping_from(exp);
1163 let upper_limit = MAX_BASE_64[exp_usize]; let x = root_estimate_64(n as f64, exp_usize);
1165 let mut root = u64::rounding_from(
1167 (((n / x.wrapping_pow(exp - 1)) as f64) - x as f64) * INV_TABLE[exp_usize],
1168 Down,
1169 ).0;
1170 if root >= upper_limit {
1171 root = upper_limit - 1;
1172 }
1173 let mut pow = root.pow(exp);
1174 if pow == n {
1175 return root;
1176 }
1177 while pow <= n {
1178 root += 1;
1179 pow = root.pow(exp);
1180 if root == upper_limit {
1181 break;
1182 }
1183 }
1184 while pow > n {
1185 root -= 1;
1186 pow = root.pow(exp);
1187 }
1188 if pow == n {
1189 root
1190 } else {
1191 root + 1
1192 }
1193}}
1194
1195private_test_fn! {fast_checked_root_u32(n: u32, exp: u64) -> Option<u32> {
1196 assert_ne!(exp, 0);
1197 if n < 2 || exp == 1 {
1198 return Some(n);
1199 }
1200 if exp >= u32::WIDTH || n.significant_bits() <= exp {
1201 return None;
1202 }
1203 if exp == 2 {
1204 return n.checked_sqrt();
1205 }
1206 if exp == 3 {
1207 let root = cbrt_chebyshev_approx_u32(n);
1208 return if root.pow(3) == n { Some(root) } else { None };
1209 }
1210 let exp = u32::wrapping_from(exp);
1211 let exp_usize = usize::wrapping_from(exp);
1212 let upper_limit = MAX_BASE_32[exp_usize]; let x = root_estimate_32(f64::from(n), exp_usize);
1214 let mut root = u32::rounding_from(
1216 (f64::from(n / x.pow(exp - 1)) - f64::from(x)) * INV_TABLE[exp_usize],
1217 Down,
1218 ).0;
1219 if root >= upper_limit {
1220 root = upper_limit - 1;
1221 }
1222 let mut pow = root.pow(exp);
1223 if pow == n {
1224 return Some(root);
1225 }
1226 while pow <= n {
1227 root += 1;
1228 pow = root.pow(exp);
1229 if root == upper_limit {
1230 break;
1231 }
1232 }
1233 while pow > n {
1234 root -= 1;
1235 pow = root.pow(exp);
1236 }
1237 if pow == n {
1238 Some(root)
1239 } else {
1240 None
1241 }
1242}}
1243
1244private_test_fn! {fast_checked_root_u64(n: u64, exp: u64) -> Option<u64> {
1245 assert_ne!(exp, 0);
1246 if n < 2 || exp == 1 {
1247 return Some(n);
1248 }
1249 if exp >= u64::WIDTH || n.significant_bits() <= exp {
1250 return None;
1251 }
1252 if exp == 2 {
1253 return n.checked_sqrt();
1254 }
1255 if exp == 3 {
1256 let root = cbrt_chebyshev_approx_u64(n);
1257 return if root.pow(3) == n { Some(root) } else { None };
1258 }
1259 let exp = u32::wrapping_from(exp);
1260 let exp_usize = usize::wrapping_from(exp);
1261 let upper_limit = MAX_BASE_64[exp_usize]; let x = root_estimate_64(n as f64, exp_usize);
1263 let mut root = u64::rounding_from(
1265 (((n / x.wrapping_pow(exp - 1)) as f64) - x as f64) * INV_TABLE[exp_usize],
1266 Down,
1267 ).0;
1268 if root >= upper_limit {
1269 root = upper_limit - 1;
1270 }
1271 let mut pow = root.pow(exp);
1272 if pow == n {
1273 return Some(root);
1274 }
1275 while pow <= n {
1276 root += 1;
1277 pow = root.pow(exp);
1278 if root == upper_limit {
1279 break;
1280 }
1281 }
1282 while pow > n {
1283 root -= 1;
1284 pow = root.pow(exp);
1285 }
1286 if pow == n {
1287 Some(root)
1288 } else {
1289 None
1290 }
1291}}
1292
1293private_test_fn! {fast_root_rem_u32(n: u32, exp: u64) -> (u32, u32) {
1294 assert_ne!(exp, 0);
1295 if n < 2 || exp == 1 {
1296 return (n, 0);
1297 }
1298 if exp >= u32::WIDTH || n.significant_bits() <= exp {
1299 return (1, n - 1);
1300 }
1301 if exp == 2 {
1302 return n.sqrt_rem();
1303 }
1304 if exp == 3 {
1305 let root = cbrt_chebyshev_approx_u32(n);
1306 let pow = root.pow(3);
1307 return (root, n - pow);
1308 }
1309 let exp = u32::wrapping_from(exp);
1310 let exp_usize = usize::wrapping_from(exp);
1311 let upper_limit = MAX_BASE_32[exp_usize]; let x = root_estimate_32(f64::from(n), exp_usize);
1313 let mut root = u32::rounding_from(
1315 (f64::from(n / x.pow(exp - 1)) - f64::from(x)) * INV_TABLE[exp_usize],
1316 Down,
1317 ).0;
1318 if root >= upper_limit {
1319 root = upper_limit - 1;
1320 }
1321 let mut pow = root.pow(exp);
1322 if pow == n {
1323 return (root, 0);
1324 }
1325 while pow <= n {
1326 root += 1;
1327 pow = root.pow(exp);
1328 if root == upper_limit {
1329 break;
1330 }
1331 }
1332 while pow > n {
1333 root -= 1;
1334 pow = root.pow(exp);
1335 }
1336 (root, n - pow)
1337}}
1338
1339private_test_fn! {fast_root_rem_u64(n: u64, exp: u64) -> (u64, u64) {
1340 assert_ne!(exp, 0);
1341 if n < 2 || exp == 1 {
1342 return (n, 0);
1343 }
1344 if exp >= u64::WIDTH || n.significant_bits() <= exp {
1345 return (1, n - 1);
1346 }
1347 if exp == 2 {
1348 return n.sqrt_rem();
1349 }
1350 if exp == 3 {
1351 let root = cbrt_chebyshev_approx_u64(n);
1352 let pow = root.pow(3);
1353 return (root, n - pow);
1354 }
1355 let exp = u32::wrapping_from(exp);
1356 let exp_usize = usize::wrapping_from(exp);
1357 let upper_limit = MAX_BASE_64[exp_usize]; let x = root_estimate_64(n as f64, exp_usize);
1359 let mut root = u64::rounding_from(
1361 (((n / x.wrapping_pow(exp - 1)) as f64) - x as f64) * INV_TABLE[exp_usize],
1362 Down,
1363 ).0;
1364 if root >= upper_limit {
1365 root = upper_limit - 1;
1366 }
1367 let mut pow = root.pow(exp);
1368 if pow == n {
1369 return (root, 0);
1370 }
1371 while pow <= n {
1372 root += 1;
1373 pow = root.pow(exp);
1374 if root == upper_limit {
1375 break;
1376 }
1377 }
1378 while pow > n {
1379 root -= 1;
1380 pow = root.pow(exp);
1381 }
1382 (root, n - pow)
1383}}
1384
1385#[cfg(feature = "test_build")]
1386pub fn floor_root_binary<T: PrimitiveUnsigned>(x: T, exp: u64) -> T {
1387 if exp == 0 {
1388 panic!("Cannot take 0th root");
1389 } else if exp == 1 || x < T::TWO {
1390 x
1391 } else {
1392 let bits = x.significant_bits();
1393 if bits <= exp {
1394 T::ONE
1395 } else {
1396 let p = T::power_of_2(bits.div_round(exp, Ceiling).0);
1397 floor_inverse_checked_binary(|i| i.checked_pow(exp), x, p >> 1, p)
1398 }
1399 }
1400}
1401
1402#[cfg(feature = "test_build")]
1403pub fn ceiling_root_binary<T: PrimitiveUnsigned>(x: T, exp: u64) -> T {
1404 let floor_root = floor_root_binary(x, exp);
1405 if floor_root.pow(exp) == x {
1406 floor_root
1407 } else {
1408 floor_root + T::ONE
1409 }
1410}
1411
1412#[cfg(feature = "test_build")]
1413pub fn checked_root_binary<T: PrimitiveUnsigned>(x: T, exp: u64) -> Option<T> {
1414 let floor_root = floor_root_binary(x, exp);
1415 if floor_root.pow(exp) == x {
1416 Some(floor_root)
1417 } else {
1418 None
1419 }
1420}
1421
1422#[cfg(feature = "test_build")]
1423pub fn root_rem_binary<T: PrimitiveUnsigned>(x: T, exp: u64) -> (T, T) {
1424 let floor_root = floor_root_binary(x, exp);
1425 (floor_root, x - floor_root.pow(exp))
1426}
1427
1428impl FloorRoot<u64> for u8 {
1429 type Output = Self;
1430
1431 #[inline]
1447 fn floor_root(self, exp: u64) -> Self {
1448 match (self, exp) {
1449 (_, 0) => panic!(),
1450 (0 | 1, _) | (_, 1) => self,
1451 (_, 8..=u64::MAX) => 1,
1452 (x, 2) => x.floor_sqrt(),
1453 (x, 3) => Self::wrapping_from(match U8_CUBES.binary_search(&x) {
1454 Ok(i) => i,
1455 Err(i) => i - 1,
1456 }),
1457 (x, 4) if x < 16 => 1,
1458 (x, 4) if x < 81 => 2,
1459 (x, 5) if x < 32 => 1,
1460 (x, 5) if x < 243 => 2,
1461 (_, 4 | 5) => 3,
1462 (x, 6) if x < 64 => 1,
1463 (x, 7) if x < 128 => 1,
1464 (_, 6 | 7) => 2,
1465 }
1466 }
1467}
1468
1469impl CeilingRoot<u64> for u8 {
1470 type Output = Self;
1471
1472 fn ceiling_root(self, exp: u64) -> Self {
1488 match (self, exp) {
1489 (_, 0) => panic!(),
1490 (0 | 1, _) | (_, 1) => self,
1491 (_, 8..=u64::MAX) => 2,
1492 (x, 2) => x.ceiling_sqrt(),
1493 (x, 3) => Self::wrapping_from(match U8_CUBES.binary_search(&x) {
1494 Ok(i) | Err(i) => i,
1495 }),
1496 (x, 4) if x <= 16 => 2,
1497 (x, 4) if x <= 81 => 3,
1498 (x, 5) if x <= 32 => 2,
1499 (x, 5) if x <= 243 => 3,
1500 (_, 4 | 5) => 4,
1501 (x, 6) if x <= 64 => 2,
1502 (x, 7) if x <= 128 => 2,
1503 (_, 6 | 7) => 3,
1504 }
1505 }
1506}
1507
1508impl CheckedRoot<u64> for u8 {
1509 type Output = Self;
1510
1511 fn checked_root(self, exp: u64) -> Option<Self> {
1533 match (self, exp) {
1534 (_, 0) => panic!(),
1535 (0 | 1, _) | (_, 1) => Some(self),
1536 (x, 2) => x.checked_sqrt(),
1537 (x, 3) => U8_CUBES.binary_search(&x).ok().map(Self::wrapping_from),
1538 (16, 4) | (32, 5) | (64, 6) | (128, 7) => Some(2),
1539 (81, 4) | (243, 5) => Some(3),
1540 _ => None,
1541 }
1542 }
1543}
1544
1545impl RootRem<u64> for u8 {
1546 type RootOutput = Self;
1547 type RemOutput = Self;
1548
1549 fn root_rem(self, exp: u64) -> (Self, Self) {
1566 match (self, exp) {
1567 (_, 0) => panic!(),
1568 (0 | 1, _) | (_, 1) => (self, 0),
1569 (x, 8..=u64::MAX) => (1, x - 1),
1570 (x, 2) => x.sqrt_rem(),
1571 (x, 3) => match U8_CUBES.binary_search(&x) {
1572 Ok(i) => (Self::wrapping_from(i), 0),
1573 Err(i) => (Self::wrapping_from(i - 1), x - U8_CUBES[i - 1]),
1574 },
1575 (x, 4) if x < 16 => (1, x - 1),
1576 (x, 4) if x < 81 => (2, x - 16),
1577 (x, 4) => (3, x - 81),
1578 (x, 5) if x < 32 => (1, x - 1),
1579 (x, 5) if x < 243 => (2, x - 32),
1580 (x, 5) => (3, x - 243),
1581 (x, 6) if x < 64 => (1, x - 1),
1582 (x, 6) => (2, x - 64),
1583 (x, 7) if x < 128 => (1, x - 1),
1584 (x, 7) => (2, x - 128),
1585 }
1586 }
1587}
1588
1589impl FloorRoot<u64> for u16 {
1590 type Output = Self;
1591
1592 #[inline]
1608 fn floor_root(self, exp: u64) -> Self {
1609 Self::wrapping_from(u32::from(self).floor_root(exp))
1610 }
1611}
1612
1613impl CeilingRoot<u64> for u16 {
1614 type Output = Self;
1615
1616 #[inline]
1632 fn ceiling_root(self, exp: u64) -> Self {
1633 Self::wrapping_from(u32::from(self).ceiling_root(exp))
1634 }
1635}
1636
1637impl CheckedRoot<u64> for u16 {
1638 type Output = Self;
1639
1640 #[inline]
1662 fn checked_root(self, exp: u64) -> Option<Self> {
1663 u32::from(self).checked_root(exp).map(Self::wrapping_from)
1664 }
1665}
1666
1667impl RootRem<u64> for u16 {
1668 type RootOutput = Self;
1669 type RemOutput = Self;
1670
1671 #[inline]
1688 fn root_rem(self, exp: u64) -> (Self, Self) {
1689 let (sqrt, rem) = u32::from(self).root_rem(exp);
1690 (Self::wrapping_from(sqrt), Self::wrapping_from(rem))
1691 }
1692}
1693
1694impl FloorRoot<u64> for u32 {
1695 type Output = Self;
1696
1697 #[inline]
1715 fn floor_root(self, exp: u64) -> Self {
1716 fast_floor_root_u32(self, exp)
1717 }
1718}
1719
1720impl CeilingRoot<u64> for u32 {
1721 type Output = Self;
1722
1723 #[inline]
1741 fn ceiling_root(self, exp: u64) -> Self {
1742 fast_ceiling_root_u32(self, exp)
1743 }
1744}
1745
1746impl CheckedRoot<u64> for u32 {
1747 type Output = Self;
1748
1749 #[inline]
1773 fn checked_root(self, exp: u64) -> Option<Self> {
1774 fast_checked_root_u32(self, exp)
1775 }
1776}
1777
1778impl RootRem<u64> for u32 {
1779 type RootOutput = Self;
1780 type RemOutput = Self;
1781
1782 #[inline]
1801 fn root_rem(self, exp: u64) -> (Self, Self) {
1802 fast_root_rem_u32(self, exp)
1803 }
1804}
1805
1806impl FloorRoot<Self> for u64 {
1807 type Output = Self;
1808
1809 #[inline]
1827 fn floor_root(self, exp: Self) -> Self {
1828 fast_floor_root_u64(self, exp)
1829 }
1830}
1831
1832impl CeilingRoot<Self> for u64 {
1833 type Output = Self;
1834
1835 #[inline]
1853 fn ceiling_root(self, exp: Self) -> Self {
1854 fast_ceiling_root_u64(self, exp)
1855 }
1856}
1857
1858impl CheckedRoot<Self> for u64 {
1859 type Output = Self;
1860
1861 #[inline]
1885 fn checked_root(self, exp: Self) -> Option<Self> {
1886 fast_checked_root_u64(self, exp)
1887 }
1888}
1889
1890impl RootRem<Self> for u64 {
1891 type RootOutput = Self;
1892 type RemOutput = Self;
1893
1894 #[inline]
1913 fn root_rem(self, exp: Self) -> (Self, Self) {
1914 fast_root_rem_u64(self, exp)
1915 }
1916}
1917
1918impl FloorRoot<u64> for usize {
1919 type Output = Self;
1920
1921 #[inline]
1937 fn floor_root(self, exp: u64) -> Self {
1938 if USIZE_IS_U32 {
1939 Self::wrapping_from(u32::wrapping_from(self).floor_root(exp))
1940 } else {
1941 Self::wrapping_from(u64::wrapping_from(self).floor_root(exp))
1942 }
1943 }
1944}
1945
1946impl CeilingRoot<u64> for usize {
1947 type Output = Self;
1948
1949 #[inline]
1965 fn ceiling_root(self, exp: u64) -> Self {
1966 if USIZE_IS_U32 {
1967 Self::wrapping_from(u32::wrapping_from(self).ceiling_root(exp))
1968 } else {
1969 Self::wrapping_from(u64::wrapping_from(self).ceiling_root(exp))
1970 }
1971 }
1972}
1973
1974impl CheckedRoot<u64> for usize {
1975 type Output = Self;
1976
1977 #[inline]
1999 fn checked_root(self, exp: u64) -> Option<Self> {
2000 if USIZE_IS_U32 {
2001 u32::wrapping_from(self)
2002 .checked_root(exp)
2003 .map(Self::wrapping_from)
2004 } else {
2005 u64::wrapping_from(self)
2006 .checked_root(exp)
2007 .map(Self::wrapping_from)
2008 }
2009 }
2010}
2011
2012impl RootRem<u64> for usize {
2013 type RootOutput = Self;
2014 type RemOutput = Self;
2015
2016 #[inline]
2033 fn root_rem(self, exp: u64) -> (Self, Self) {
2034 if USIZE_IS_U32 {
2035 let (sqrt, rem) = u32::wrapping_from(self).root_rem(exp);
2036 (Self::wrapping_from(sqrt), Self::wrapping_from(rem))
2037 } else {
2038 let (sqrt, rem) = u64::wrapping_from(self).root_rem(exp);
2039 (Self::wrapping_from(sqrt), Self::wrapping_from(rem))
2040 }
2041 }
2042}
2043
2044impl FloorRoot<u64> for u128 {
2045 type Output = Self;
2046
2047 fn floor_root(self, exp: u64) -> Self {
2071 if exp == 2 {
2072 return self.floor_sqrt();
2073 }
2074 floor_root_approx_and_refine(|x| x as f64, |x| x as Self, self, exp)
2075 }
2076}
2077
2078impl CeilingRoot<u64> for u128 {
2079 type Output = Self;
2080
2081 fn ceiling_root(self, exp: u64) -> Self {
2105 if exp == 2 {
2106 return self.ceiling_sqrt();
2107 }
2108 let root = floor_root_approx_and_refine(|x| x as f64, |x| x as Self, self, exp);
2109 if root.pow(u32::saturating_from(exp)) == self {
2110 root
2111 } else {
2112 root + 1
2113 }
2114 }
2115}
2116
2117impl CheckedRoot<u64> for u128 {
2118 type Output = Self;
2119
2120 fn checked_root(self, exp: u64) -> Option<Self> {
2150 if exp == 2 {
2151 return self.checked_sqrt();
2152 }
2153 let root = floor_root_approx_and_refine(|x| x as f64, |x| x as Self, self, exp);
2154 if root.pow(u32::saturating_from(exp)) == self {
2155 Some(root)
2156 } else {
2157 None
2158 }
2159 }
2160}
2161
2162impl RootRem<u64> for u128 {
2163 type RootOutput = Self;
2164 type RemOutput = Self;
2165
2166 fn root_rem(self, exp: u64) -> (Self, Self) {
2191 if exp == 2 {
2192 return self.sqrt_rem();
2193 }
2194 let root = floor_root_approx_and_refine(|x| x as f64, |x| x as Self, self, exp);
2195 (root, self - root.pow(u32::saturating_from(exp)))
2196 }
2197}
2198
2199macro_rules! impl_root_assign_rem {
2200 ($t: ident) => {
2201 impl RootAssignRem<u64> for $t {
2202 type RemOutput = $t;
2203
2204 #[inline]
2227 fn root_assign_rem(&mut self, exp: u64) -> $t {
2228 let rem;
2229 (*self, rem) = self.root_rem(exp);
2230 rem
2231 }
2232 }
2233 };
2234}
2235apply_to_unsigneds!(impl_root_assign_rem);
2236
2237macro_rules! impl_root_signed {
2238 ($t: ident) => {
2239 impl FloorRoot<u64> for $t {
2240 type Output = $t;
2241
2242 #[inline]
2262 fn floor_root(self, exp: u64) -> $t {
2263 if self >= 0 {
2264 $t::wrapping_from(self.unsigned_abs().floor_root(exp))
2265 } else if exp.odd() {
2266 $t::wrapping_from(self.unsigned_abs().ceiling_root(exp)).wrapping_neg()
2267 } else {
2268 panic!("Cannot take even root of a negative number");
2269 }
2270 }
2271 }
2272
2273 impl CeilingRoot<u64> for $t {
2274 type Output = $t;
2275
2276 #[inline]
2296 fn ceiling_root(self, exp: u64) -> $t {
2297 if self >= 0 {
2298 $t::wrapping_from(self.unsigned_abs().ceiling_root(exp))
2299 } else if exp.odd() {
2300 $t::wrapping_from(self.unsigned_abs().floor_root(exp)).wrapping_neg()
2301 } else {
2302 panic!("Cannot take even root of a negative number");
2303 }
2304 }
2305 }
2306
2307 impl CheckedRoot<u64> for $t {
2308 type Output = $t;
2309
2310 #[inline]
2336 fn checked_root(self, exp: u64) -> Option<$t> {
2337 if self >= 0 {
2338 self.unsigned_abs().checked_root(exp).map($t::wrapping_from)
2339 } else if exp.odd() {
2340 self.unsigned_abs()
2341 .checked_root(exp)
2342 .map(|x| $t::wrapping_from(x).wrapping_neg())
2343 } else {
2344 panic!("Cannot take even root of a negative number");
2345 }
2346 }
2347 }
2348 };
2349}
2350apply_to_signeds!(impl_root_signed);
2351
2352macro_rules! impl_root_primitive_int {
2353 ($t: ident) => {
2354 impl FloorRootAssign<u64> for $t {
2355 #[inline]
2375 fn floor_root_assign(&mut self, exp: u64) {
2376 *self = self.floor_root(exp);
2377 }
2378 }
2379
2380 impl CeilingRootAssign<u64> for $t {
2381 #[inline]
2401 fn ceiling_root_assign(&mut self, exp: u64) {
2402 *self = self.ceiling_root(exp);
2403 }
2404 }
2405 };
2406}
2407apply_to_primitive_ints!(impl_root_primitive_int);