malachite_base/num/factorization/is_power.rs
1// Copyright © 2026 William Youmans
2//
3// Uses code adopted from the FLINT Library.
4//
5// Copyright © 2009 William Hart
6//
7// This file is part of Malachite.
8//
9// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
10// Lesser General Public License (LGPL as published by the Free Software Foundation; either version
11// 3 of the License, or (at your option any later version. See <https://www.gnu.org/licenses/>.
12
13use crate::num::arithmetic::traits::{
14 CheckedRoot, DivAssignMod, DivMod, GcdAssign, Parity, RootRem, SqrtRem,
15};
16use crate::num::basic::integers::USIZE_IS_U32;
17use crate::num::conversion::traits::{ExactFrom, WrappingFrom};
18use crate::num::factorization::primes::SMALL_PRIMES;
19use crate::num::factorization::traits::{
20 ExpressAsPower, Factor, IsPower, IsPrime, IsSquare, Primes,
21};
22use crate::num::logic::traits::{SignificantBits, TrailingZeros};
23
24// The following arrays are bitmasks indicating whether an integer is a 2, 3, or 5th power residue.
25// For example, modulo 31 we have:
26// - squares: {0, 1, 2, 4, 5, 7, 8, 9, 10, 14, 16, 18, 19, 20, 25, 28}
27// - cubes: {0, 1, 2, 4, 8, 15, 16, 23, 27, 29, 30}
28// - 5th powers: {0, 1, 5, 6, 25, 26, 30}
29// Since 2 is a square, cube, but not a 5th power mod 31, we encode it as 011 = 3. Then MOD31[2] =
30// 3.
31
32const MOD63: [u8; 63] = [
33 7, 7, 4, 0, 5, 4, 0, 5, 6, 5, 4, 4, 0, 4, 4, 0, 5, 4, 5, 4, 4, 0, 5, 4, 0, 5, 4, 6, 7, 4, 0, 4,
34 4, 0, 4, 6, 7, 5, 4, 0, 4, 4, 0, 5, 4, 4, 5, 4, 0, 5, 4, 0, 4, 4, 4, 6, 4, 0, 5, 4, 0, 4, 6,
35];
36
37const MOD61: [u8; 61] = [
38 7, 7, 0, 3, 1, 1, 0, 0, 2, 3, 0, 6, 1, 5, 5, 1, 1, 0, 0, 1, 3, 4, 1, 2, 2, 1, 0, 3, 2, 4, 0, 0,
39 4, 2, 3, 0, 1, 2, 2, 1, 4, 3, 1, 0, 0, 1, 1, 5, 5, 1, 6, 0, 3, 2, 0, 0, 1, 1, 3, 0, 7,
40];
41
42const MOD44: [u8; 44] = [
43 7, 7, 0, 2, 3, 3, 0, 2, 2, 3, 0, 6, 7, 2, 0, 2, 3, 2, 0, 2, 3, 6, 0, 6, 2, 3, 0, 2, 2, 2, 0, 2,
44 6, 7, 0, 2, 3, 3, 0, 2, 2, 2, 0, 6,
45];
46
47const MOD31: [u8; 31] =
48 [7, 7, 3, 0, 3, 5, 4, 1, 3, 1, 1, 0, 0, 0, 1, 2, 3, 0, 1, 1, 1, 0, 0, 2, 0, 5, 4, 2, 1, 2, 6];
49
50const MOD72: [u8; 72] = [
51 7, 7, 0, 0, 0, 7, 0, 7, 7, 7, 0, 7, 0, 7, 0, 0, 7, 7, 0, 7, 0, 0, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7,
52 7, 0, 0, 7, 0, 7, 0, 0, 7, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 0, 0, 7, 0, 7, 7, 0, 0, 7, 0, 7, 0, 7,
53 7, 7, 0, 7, 0, 0, 0, 7,
54];
55
56const MOD49: [u8; 49] = [
57 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
58 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
59];
60
61const MOD67: [u8; 67] = [
62 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0,
63 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
64 0, 0, 2,
65];
66
67const MOD79: [u8; 79] = [
68 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0,
69 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0,
70 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4,
71];
72
73// This is n_is_power when FLINT64 is false, from ulong_extras/is_power.c, FLINT 3.1.2.
74fn get_perfect_power_u32(n: u32) -> Option<(u32, u64)> {
75 // Check for powers 2, 3, 5
76 let mut t = MOD31[(n % 31) as usize];
77 t &= MOD44[(n % 44) as usize];
78 t &= MOD61[(n % 61) as usize];
79 t &= MOD63[(n % 63) as usize];
80 // Check for perfect square
81 if t.odd() {
82 let (rt, rem) = n.sqrt_rem();
83 if rem == 0 {
84 return Some((rt, 2));
85 }
86 }
87 // Check for perfect cube
88 if t & 2 != 0 {
89 let (rt, rem) = n.root_rem(3);
90 if rem == 0 {
91 return Some((rt, 3));
92 }
93 }
94 // Check for perfect fifth power
95 if t & 4 != 0 {
96 let (rt, rem) = n.root_rem(5);
97 if rem == 0 {
98 return Some((rt, 5));
99 }
100 }
101 // Check for powers 7, 11, 13
102 t = MOD49[(n % 49) as usize];
103 t |= MOD67[(n % 67) as usize];
104 t |= MOD79[(n % 79) as usize];
105 t &= MOD72[(n % 72) as usize];
106
107 // Check for perfect 7th power
108 if t.odd() {
109 let (rt, rem) = n.root_rem(7);
110 if rem == 0 {
111 return Some((rt, 7));
112 }
113 }
114 // Check for perfect 11th power
115 if t & 2 != 0 {
116 let (rt, rem) = n.root_rem(11);
117 if rem == 0 {
118 return Some((rt, 11));
119 }
120 }
121 // Check for perfect 13th power
122 if t & 13 != 0 {
123 let (rt, rem) = n.root_rem(13);
124 if rem == 0 {
125 return Some((rt, 13));
126 }
127 }
128 // Handle powers of 2
129 let count = u64::from(n.trailing_zeros());
130 let mut n = n >> count;
131 if n == 1 {
132 return if count == 1 {
133 None // Just 2^1 = 2, not a perfect power
134 } else {
135 Some((2, count))
136 };
137 }
138 // Check other powers (exp >= 17, root <= 13 and odd)
139 let mut exp = 0;
140 while n.is_multiple_of(3) {
141 n /= 3;
142 exp += 1;
143 }
144 if exp > 0 {
145 if n == 1 && exp > 1 {
146 if count == 0 {
147 return Some((3, exp));
148 } else if count == exp {
149 return Some((6, exp));
150 } else if count == exp << 1 {
151 return Some((12, exp));
152 }
153 }
154 return None;
155 }
156 None
157}
158
159// This is n_is_power when FLINT64 is false, from ulong_extras/is_power.c, FLINT 3.1.2, returning
160// only whether n can be expressed as a nontrivial perfect power.
161fn get_perfect_power_u32_bool(n: u32) -> bool {
162 // Check for powers 2, 3, 5
163 let mut t = MOD31[(n % 31) as usize];
164 t &= MOD44[(n % 44) as usize];
165 t &= MOD61[(n % 61) as usize];
166 t &= MOD63[(n % 63) as usize];
167 // Check for perfect squares, cubes, and fifth powers
168 if (t.odd() && n.is_square())
169 || (t & 2 != 0 && n.root_rem(3).1 == 0)
170 || (t & 4 != 0 && n.root_rem(5).1 == 0)
171 {
172 return true;
173 }
174 // Check for powers 7, 11, 13
175 t = MOD49[(n % 49) as usize];
176 t |= MOD67[(n % 67) as usize];
177 t |= MOD79[(n % 79) as usize];
178 t &= MOD72[(n % 72) as usize];
179 // Check for perfect 7th, 11th, and 13th powers
180 if (t.odd() && n.root_rem(7).1 == 0)
181 || (t & 2 != 0 && n.root_rem(11).1 == 0)
182 || (t & 13 != 0 && n.root_rem(13).1 == 0)
183 {
184 return true;
185 }
186 // Handle powers of 2
187 let count = n.trailing_zeros();
188 let mut n = n >> n.trailing_zeros();
189 if n == 1 {
190 return count != 1;
191 }
192 // Check other powers (exp >= 17, root <= 13 and odd)
193 let mut exp = 0;
194 while n.is_multiple_of(3) {
195 n /= 3;
196 exp += 1;
197 }
198 exp > 0 && n == 1 && exp > 1 && (count == 0 || count == exp || count == exp << 1)
199}
200
201// This is n_is_power when FLINT64 is true, from ulong_extras/is_power.c, FLINT 3.1.2.
202fn get_perfect_power_u64(n: u64) -> Option<(u64, u64)> {
203 // Check for powers 2, 3, 5
204 let mut t = MOD31[(n % 31) as usize];
205 t &= MOD44[(n % 44) as usize];
206 t &= MOD61[(n % 61) as usize];
207 t &= MOD63[(n % 63) as usize];
208 // Check for perfect square
209 if t.odd() {
210 let (rt, rem) = n.sqrt_rem();
211 if rem == 0 {
212 return Some((rt, 2));
213 }
214 }
215 // Check for perfect cube
216 if t & 2 != 0 {
217 let (rt, rem) = n.root_rem(3);
218 if rem == 0 {
219 return Some((rt, 3));
220 }
221 }
222 // Check for perfect fifth power
223 if t & 4 != 0 {
224 let (rt, rem) = n.root_rem(5);
225 if rem == 0 {
226 return Some((rt, 5));
227 }
228 }
229 // Check for powers 7, 11, 13
230 t = MOD49[(n % 49) as usize];
231 t |= MOD67[(n % 67) as usize];
232 t |= MOD79[(n % 79) as usize];
233 t &= MOD72[(n % 72) as usize];
234 // Check for perfect 7th power
235 if t.odd() {
236 let (rt, rem) = n.root_rem(7);
237 if rem == 0 {
238 return Some((rt, 7));
239 }
240 }
241 // Check for perfect 11th power
242 if t & 2 != 0 {
243 let (rt, rem) = n.root_rem(11);
244 if rem == 0 {
245 return Some((rt, 11));
246 }
247 }
248 // Check for perfect 13th power
249 if t & 13 != 0 {
250 let (rt, rem) = n.root_rem(13);
251 if rem == 0 {
252 return Some((rt, 13));
253 }
254 }
255 // Handle powers of 2
256 let count = u64::from(n.trailing_zeros());
257 let mut n = n >> count;
258 if n == 1 {
259 return if count == 1 {
260 None // Just 2^1 = 2, not a perfect power
261 } else {
262 Some((2, count))
263 };
264 }
265 // Check other powers (exp >= 17, root <= 13 and odd)
266 let mut exp = 0;
267 while n.is_multiple_of(3) {
268 n /= 3;
269 exp += 1;
270 }
271 if exp > 0 {
272 if n == 1 && exp > 1 {
273 if count == 0 {
274 return Some((3, exp));
275 } else if count == exp {
276 return Some((6, exp));
277 } else if count == exp << 1 {
278 return Some((12, exp));
279 }
280 }
281 return None;
282 }
283 // Check powers of 5
284 exp = 0;
285 while n.is_multiple_of(5) {
286 n /= 5;
287 exp += 1;
288 }
289 if exp > 0 {
290 if n == 1 && exp > 1 {
291 if count == 0 {
292 return Some((5, exp));
293 } else if count == exp {
294 return Some((10, exp));
295 }
296 }
297 return None;
298 }
299 if count > 0 {
300 return None;
301 }
302 // Check powers of 7
303 exp = 0;
304 while n.is_multiple_of(7) {
305 n /= 7;
306 exp += 1;
307 }
308 if exp > 0 {
309 if n == 1 && exp > 1 {
310 return Some((7, exp));
311 }
312 return None;
313 }
314 // Check powers of 11
315 exp = 0;
316 while n.is_multiple_of(11) {
317 n /= 11;
318 exp += 1;
319 }
320 if exp > 0 {
321 if n == 1 && exp > 1 {
322 return Some((11, exp));
323 }
324 return None;
325 }
326 // Check powers of 13
327 exp = 0;
328 while n.is_multiple_of(13) {
329 n /= 13;
330 exp += 1;
331 }
332 if exp > 0 {
333 if n == 1 && exp > 1 {
334 return Some((13, exp));
335 }
336 return None;
337 }
338 None
339}
340
341// This is n_is_power when FLINT64 is true, from ulong_extras/is_power.c, FLINT 3.1.2, returning
342// only whether n can be expressed as a nontrivial perfect power.
343fn get_perfect_power_u64_bool(n: u64) -> bool {
344 // Check for powers 2, 3, 5
345 let mut t = MOD31[(n % 31) as usize];
346 t &= MOD44[(n % 44) as usize];
347 t &= MOD61[(n % 61) as usize];
348 t &= MOD63[(n % 63) as usize];
349 // Check for perfect squares, cubes, and fifth powers
350 if (t.odd() && n.is_square())
351 || (t & 2 != 0 && n.root_rem(3).1 == 0)
352 || (t & 4 != 0 && n.root_rem(5).1 == 0)
353 {
354 return true;
355 }
356 // Check for powers 7, 11, 13
357 t = MOD49[(n % 49) as usize];
358 t |= MOD67[(n % 67) as usize];
359 t |= MOD79[(n % 79) as usize];
360 t &= MOD72[(n % 72) as usize];
361 // Check for perfect 7th, 11th, and 13th powers
362 if (t.odd() && n.root_rem(7).1 == 0)
363 || (t & 2 != 0 && n.root_rem(11).1 == 0)
364 || (t & 13 != 0 && n.root_rem(13).1 == 0)
365 {
366 return true;
367 }
368 // Handle powers of 2
369 let count = u64::from(n.trailing_zeros());
370 let mut n = n >> count;
371 if n == 1 {
372 return count != 1;
373 }
374 // Check other powers (exp >= 17, root <= 13 and odd)
375 let mut exp = 0;
376 while n.is_multiple_of(3) {
377 n /= 3;
378 exp += 1;
379 }
380 if exp > 0 {
381 return n == 1 && exp > 1 && (count == 0 || count == exp || count == exp << 1);
382 }
383 // Check powers of 5
384 exp = 0;
385 while n.is_multiple_of(5) {
386 n /= 5;
387 exp += 1;
388 }
389 if exp > 0 {
390 return n == 1 && exp > 1 && (count == 0 || count == exp);
391 }
392 if count > 0 {
393 return false;
394 }
395 // Check powers of 7
396 exp = 0;
397 while n.is_multiple_of(7) {
398 n /= 7;
399 exp += 1;
400 }
401 if exp > 0 {
402 return n == 1 && exp > 1;
403 }
404 // Check powers of 11
405 exp = 0;
406 while n.is_multiple_of(11) {
407 n /= 11;
408 exp += 1;
409 }
410 if exp > 0 {
411 return n == 1 && exp > 1;
412 }
413 // Check powers of 13
414 exp = 0;
415 while n.is_multiple_of(13) {
416 n /= 13;
417 exp += 1;
418 }
419 n == 1 && exp > 1
420}
421
422fn get_perfect_power_u128(n: u128) -> Option<(u128, u64)> {
423 if let Ok(n) = u64::try_from(n) {
424 return get_perfect_power_u64(n).map(|(p, e)| (u128::from(p), e));
425 }
426 // Find largest power of 2 dividing n
427 let mut pow_2 = TrailingZeros::trailing_zeros(n);
428 // Two divides exactly once - not a perfect power
429 if pow_2 == 1 {
430 return None;
431 }
432 // If pow_2 is prime, just check if n is a perfect pow_2-th power
433 if pow_2.is_prime() {
434 return n.checked_root(pow_2).map(|root| (root, pow_2));
435 }
436 // Divide out 2^pow_2 to get the odd part
437 let mut q = n >> pow_2;
438 // Factor out powers of small primes
439 for &prime in SMALL_PRIMES[..168].iter().skip(1) {
440 let prime = u128::from(prime);
441 let (new_q, r) = q.div_mod(prime);
442 if r == 0 {
443 q = new_q;
444 if q.div_assign_mod(prime) != 0 {
445 return None; // prime divides exactly once, reject
446 }
447 let mut pow_p = 2u64;
448 loop {
449 let (new_q, r) = q.div_mod(prime);
450 if r == 0 {
451 q = new_q;
452 pow_p += 1;
453 } else {
454 break;
455 }
456 }
457 pow_2.gcd_assign(pow_p);
458 if pow_2 == 1 {
459 return None; // we have multiplicity 1 of some factor
460 }
461 // As soon as pow_2 becomes prime, stop factoring
462 if q == 1 || pow_2.is_prime() {
463 return n.checked_root(pow_2).map(|root| (root, pow_2));
464 }
465 }
466 }
467 // After factoring, check remaining cases
468 if pow_2 == 0 {
469 // No factors found above; exhaustively check all prime exponents
470 let bits = n.significant_bits();
471 for nth in u64::primes() {
472 // Terminate if exponent exceeds bit length (n ^ (1 / nth) < 2 for nth > bits)
473 if nth > bits {
474 return None;
475 }
476 if let Some(root) = n.checked_root(nth) {
477 return Some((root, nth));
478 }
479 }
480 } else {
481 // Found some factors; only check prime divisors of pow_2
482 for (nth, _) in pow_2.factor() {
483 if let Some(root) = n.checked_root(nth) {
484 return Some((root, nth));
485 }
486 }
487 }
488 None
489}
490
491fn get_perfect_power_u128_bool(n: u128) -> bool {
492 if let Ok(n) = u64::try_from(n) {
493 return get_perfect_power_u64_bool(n);
494 }
495 // Find largest power of 2 dividing n
496 let mut pow_2 = TrailingZeros::trailing_zeros(n);
497 // Two divides exactly once - not a perfect power
498 if pow_2 == 1 {
499 return false;
500 }
501 // If pow_2 is prime, check if n is a perfect pow_2-th power
502 if pow_2.is_prime() {
503 return n.checked_root(pow_2).is_some();
504 }
505 // Divide out 2^pow_2 to get the odd part
506 let mut q = n >> pow_2;
507 // Factor out powers of small primes
508 for &prime in SMALL_PRIMES[..168].iter().skip(1) {
509 let prime = u128::from(prime);
510 let (new_q, r) = q.div_mod(prime);
511 if r == 0 {
512 q = new_q;
513 if q.div_assign_mod(prime) != 0 {
514 return false; // prime divides exactly once, reject
515 }
516 let mut pow_p = 2u64;
517 loop {
518 let (new_q, r) = q.div_mod(prime);
519 if r == 0 {
520 q = new_q;
521 pow_p += 1;
522 } else {
523 break;
524 }
525 }
526 pow_2.gcd_assign(pow_p);
527 if pow_2 == 1 {
528 return false; // we have multiplicity 1 of some factor
529 }
530 // As soon as pow_2 becomes prime, stop factoring
531 if q == 1 || pow_2.is_prime() {
532 return n.checked_root(pow_2).is_some();
533 }
534 }
535 }
536 // After factoring, check remaining cases
537 if pow_2 == 0 {
538 // No factors found above; exhaustively check all prime exponents
539 let bits = n.significant_bits();
540 for nth in u64::primes() {
541 // Terminate if exponent exceeds bit length (n ^ (1 / nth) < 2 for nth > bits)
542 if nth > bits {
543 return false;
544 }
545 if n.checked_root(nth).is_some() {
546 return true;
547 }
548 }
549 } else {
550 // Found some factors; only check prime divisors of pow_2
551 for (nth, _) in pow_2.factor() {
552 if n.checked_root(nth).is_some() {
553 return true;
554 }
555 }
556 }
557 false
558}
559
560fn express_as_power_u32(n: u32) -> Option<(u32, u64)> {
561 if n <= 1 {
562 return Some((n, 2));
563 }
564 // continue until we have largest possible exponent
565 let (mut base, mut exp) = get_perfect_power_u32(n)?;
566 while base > 3 {
567 match get_perfect_power_u32(base) {
568 Some((base2, exp2)) => {
569 base = base2;
570 exp *= exp2;
571 }
572 None => {
573 return Some((base, exp));
574 }
575 }
576 }
577 Some((base, exp))
578}
579
580fn express_as_power_u64(n: u64) -> Option<(u64, u64)> {
581 if n <= 1 {
582 return Some((n, 2));
583 }
584 // continue until we have largest possible exponent
585 let (mut base, mut exp) = get_perfect_power_u64(n)?;
586 while base > 3 {
587 match get_perfect_power_u64(base) {
588 Some((base2, exp2)) => {
589 base = base2;
590 exp *= exp2;
591 }
592 None => {
593 return Some((base, exp));
594 }
595 }
596 }
597 Some((base, exp))
598}
599
600fn express_as_power_u128(n: u128) -> Option<(u128, u64)> {
601 if n <= 1 {
602 return Some((n, 2));
603 }
604 // continue until we have largest possible exponent
605 let (mut base, mut exp) = get_perfect_power_u128(n)?;
606 while base > 3 {
607 match get_perfect_power_u128(base) {
608 Some((base2, exp2)) => {
609 base = base2;
610 exp *= exp2;
611 }
612 None => {
613 return Some((base, exp));
614 }
615 }
616 }
617 Some((base, exp))
618}
619
620fn express_as_power_i32(n: i32) -> Option<(i32, u64)> {
621 if n == 0 || n == 1 {
622 return Some((n, 2));
623 }
624 // continue until we have largest possible exponent
625 let (mut base, mut exp) = get_perfect_power_u32(n.unsigned_abs())?;
626 while base > 3 {
627 match get_perfect_power_u32(base) {
628 Some((base2, exp2)) => {
629 base = base2;
630 exp *= exp2;
631 }
632 None => break,
633 }
634 }
635 // handle negative input
636 if n < 0 && exp.even() {
637 while exp.even() {
638 base *= base;
639 exp >>= 1;
640 }
641 if exp == 1 {
642 return None;
643 }
644 }
645 let ibase = i32::exact_from(base);
646 Some((if n >= 0 { ibase } else { -ibase }, exp))
647}
648
649fn express_as_power_i64(n: i64) -> Option<(i64, u64)> {
650 if n == 0 || n == 1 {
651 return Some((n, 2));
652 }
653 // continue until we have largest possible exponent
654 let (mut base, mut exp) = get_perfect_power_u64(n.unsigned_abs())?;
655 while base > 3 {
656 match get_perfect_power_u64(base) {
657 Some((base2, exp2)) => {
658 base = base2;
659 exp *= exp2;
660 }
661 None => break,
662 }
663 }
664 // handle negative input
665 if n < 0 && exp.even() {
666 while exp.even() {
667 base *= base;
668 exp >>= 1;
669 }
670 if exp == 1 {
671 return None;
672 }
673 }
674 let ibase = i64::exact_from(base);
675 Some((if n >= 0 { ibase } else { -ibase }, exp))
676}
677
678fn express_as_power_i128(n: i128) -> Option<(i128, u64)> {
679 if n == 0 || n == 1 {
680 return Some((n, 2));
681 }
682 // continue until we have largest possible exponent
683 let (mut base, mut exp) = get_perfect_power_u128(n.unsigned_abs())?;
684 while base > 3 {
685 match get_perfect_power_u128(base) {
686 Some((base2, exp2)) => {
687 base = base2;
688 exp *= exp2;
689 }
690 None => break,
691 }
692 }
693 // handle negative input
694 if n < 0 && exp.even() {
695 while exp.even() {
696 base *= base;
697 exp >>= 1;
698 }
699 if exp == 1 {
700 return None;
701 }
702 }
703 let ibase = i128::exact_from(base);
704 Some((if n >= 0 { ibase } else { -ibase }, exp))
705}
706
707#[inline]
708fn is_power_u32(n: u32) -> bool {
709 n <= 1 || get_perfect_power_u32_bool(n)
710}
711
712#[inline]
713fn is_power_u64(n: u64) -> bool {
714 n <= 1 || get_perfect_power_u64_bool(n)
715}
716
717fn is_power_i32(n: i32) -> bool {
718 if n == 0 || n == 1 {
719 return true;
720 }
721 if n > 0 {
722 // For positive numbers, just check if it's a perfect power
723 return get_perfect_power_u32_bool(n.unsigned_abs());
724 }
725 // For negative numbers, we need to check if there's an odd exponent representation
726 //
727 // continue until we have largest possible exponent
728 let Some((mut base, mut exp)) = get_perfect_power_u32(n.unsigned_abs()) else {
729 return false;
730 };
731 while base > 3 {
732 match get_perfect_power_u32(base) {
733 Some((base2, exp2)) => {
734 base = base2;
735 exp *= exp2;
736 }
737 None => break,
738 }
739 }
740 // Check if we can make the exponent odd
741 !exp.is_power_of_two()
742}
743
744fn is_power_i64(n: i64) -> bool {
745 if n == 0 || n == 1 {
746 return true;
747 }
748 if n > 0 {
749 // For positive numbers, just check if it's a perfect power
750 return get_perfect_power_u64_bool(n.unsigned_abs());
751 }
752 // For negative numbers, we need to check if there's an odd exponent representation
753 //
754 // continue until we have largest possible exponent
755 let Some((mut base, mut exp)) = get_perfect_power_u64(n.unsigned_abs()) else {
756 return false;
757 };
758 while base > 3 {
759 match get_perfect_power_u64(base) {
760 Some((base2, exp2)) => {
761 base = base2;
762 exp *= exp2;
763 }
764 None => break,
765 }
766 }
767 // Check if we can make the exponent odd
768 !exp.is_power_of_two()
769}
770
771fn is_power_i128(n: i128) -> bool {
772 if n == 0 || n == 1 {
773 return true;
774 }
775 if n > 0 {
776 // For positive numbers, just check if it's a perfect power
777 return get_perfect_power_u128_bool(n.unsigned_abs());
778 }
779 // For negative numbers, we need to check if there's an odd exponent representation
780 //
781 // continue until we have largest possible exponent
782 let Some((mut base, mut exp)) = get_perfect_power_u128(n.unsigned_abs()) else {
783 return false;
784 };
785 while base > 3 {
786 match get_perfect_power_u128(base) {
787 Some((base2, exp2)) => {
788 base = base2;
789 exp *= exp2;
790 }
791 None => break,
792 }
793 }
794 // Check if we can make the exponent odd
795 !exp.is_power_of_two()
796}
797
798impl ExpressAsPower for u64 {
799 /// Expresses a number as a perfect power, if such a representation exists. We define a perfect
800 /// power as any number of the form $a^x$ where $x > 1$, with $a$ and $x$ both integers. In
801 /// particular, 0 and 1 are considered perfect powers. If a number has more than one
802 /// representation as a power, the representation with the smallest base is returned. For
803 /// example, $64=2^6=4^3=8^2$, but this function returns `(2,6)` rather than `(4,3)` or `(8,2)`.
804 ///
805 /// # Worst-case complexity
806 /// $T(n) = O(n)$
807 ///
808 /// $M(n) = O(1)$
809 ///
810 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`: trial
811 /// division strips small prime factors, each division removing at least one bit, and a bounded
812 /// number of root extractions follow, each at worst $O(n)$.
813 ///
814 /// # Examples
815 /// See [here](super::is_power#express_as_power).
816 ///
817 /// # Notes
818 /// - This returns an [`Option`] which is either `Some((base, exp))` if the input is a perfect
819 /// power equal to $\text{base}^\text{exp}$, otherwise `None`.
820 /// - For 0 this returns `Some((0, 2))` and for 1 this returns `Some((1, 2))`.
821 #[inline]
822 fn express_as_power(&self) -> Option<(u64, u64)> {
823 express_as_power_u64(*self)
824 }
825}
826
827impl ExpressAsPower for u128 {
828 /// Expresses a number as a perfect power, if such a representation exists. We define a perfect
829 /// power as any number of the form $a^x$ where $x > 1$, with $a$ and $x$ both integers. In
830 /// particular, 0 and 1 are considered perfect powers. If a number has more than one
831 /// representation as a power, the representation with the smallest base is returned. For
832 /// example, $64=2^6=4^3=8^2$, but this function returns `(2,6)` rather than `(4,3)` or `(8,2)`.
833 ///
834 /// # Worst-case complexity
835 /// $T(n) = O(n)$
836 ///
837 /// $M(n) = O(1)$
838 ///
839 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`: trial
840 /// division strips small prime factors, each division removing at least one bit, and a bounded
841 /// number of root extractions follow, each at worst $O(n)$.
842 ///
843 /// # Examples
844 /// See [here](super::is_power#express_as_power).
845 ///
846 /// # Notes
847 /// - This returns an [`Option`] which is either `Some((base, exp))` if the input is a perfect
848 /// power equal to $\text{base}^\text{exp}$, otherwise `None`.
849 /// - For 0 this returns `Some((0, 2))` and for 1 this returns `Some((1, 2))`.
850 #[inline]
851 fn express_as_power(&self) -> Option<(Self, u64)> {
852 express_as_power_u128(*self)
853 }
854}
855
856impl ExpressAsPower for usize {
857 /// Expresses a number as a perfect power, if such a representation exists. We define a perfect
858 /// power as any number of the form $a^x$ where $x > 1$, with $a$ and $x$ both integers. In
859 /// particular, 0 and 1 are considered perfect powers. If a number has more than one
860 /// representation as a power, the representation with the smallest base is returned. For
861 /// example, $64=2^6=4^3=8^2$, but this function returns `(2,6)` rather than `(4,3)` or `(8,2)`.
862 ///
863 /// # Worst-case complexity
864 /// $T(n) = O(n)$
865 ///
866 /// $M(n) = O(1)$
867 ///
868 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`: trial
869 /// division strips small prime factors, each division removing at least one bit, and a bounded
870 /// number of root extractions follow, each at worst $O(n)$.
871 ///
872 /// # Examples
873 /// See [here](super::is_power#express_as_power).
874 ///
875 /// # Notes
876 /// - This returns an [`Option`] which is either `Some((base, exp))` if the input is a perfect
877 /// power equal to $\text{base}^\text{exp}$, otherwise `None`.
878 /// - For 0 this returns `Some((0, 2))` and for 1 this returns `Some((1, 2))`.
879 fn express_as_power(&self) -> Option<(Self, u64)> {
880 if USIZE_IS_U32 {
881 match express_as_power_u32(u32::wrapping_from(*self)) {
882 Some((base, exp)) => Some((Self::wrapping_from(base), exp)),
883 _ => None,
884 }
885 } else {
886 match express_as_power_u64(u64::wrapping_from(*self)) {
887 Some((base, exp)) => Some((Self::wrapping_from(base), exp)),
888 _ => None,
889 }
890 }
891 }
892}
893
894impl IsPower for u64 {
895 /// Determines whether an integer is a perfect power. We define a perfect power as any number of
896 /// the form $a^x$ where $x > 1$, with $a$ and $x$ both integers. In particular 0 and 1 are
897 /// considered perfect powers.
898 ///
899 /// $f(x) = (\exists b \in \Z, e \in \N : e > 1 \ \text{and} \ b^e = x)$.
900 ///
901 /// # Worst-case complexity
902 /// $T(n) = O(n)$
903 ///
904 /// $M(n) = O(1)$
905 ///
906 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`: trial
907 /// division strips small prime factors, each division removing at least one bit, and a bounded
908 /// number of root extractions follow, each at worst $O(n)$.
909 ///
910 /// # Examples
911 /// See [here](super::is_power#is_power).
912 #[inline]
913 fn is_power(&self) -> bool {
914 is_power_u64(*self)
915 }
916}
917
918impl IsPower for u128 {
919 /// Determines whether an integer is a perfect power. We define a perfect power as any number of
920 /// the form $a^x$ where $x > 1$, with $a$ and $x$ both integers. In particular 0 and 1 are
921 /// considered perfect powers.
922 ///
923 /// $f(x) = (\exists b \in \Z, e \in \N : e > 1 \ \text{and} \ b^e = x)$.
924 ///
925 /// # Worst-case complexity
926 /// $T(n) = O(n)$
927 ///
928 /// $M(n) = O(1)$
929 ///
930 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`: trial
931 /// division strips small prime factors, each division removing at least one bit, and a bounded
932 /// number of root extractions follow, each at worst $O(n)$.
933 ///
934 /// # Examples
935 /// See [here](super::is_power#is_power).
936 #[inline]
937 fn is_power(&self) -> bool {
938 get_perfect_power_u128_bool(*self)
939 }
940}
941
942impl IsPower for usize {
943 /// Determines whether an integer is a perfect power. We define a perfect power as any number of
944 /// the form $a^x$ where $x > 1$, with $a$ and $x$ both integers. In particular 0 and 1 are
945 /// considered perfect powers.
946 ///
947 /// $f(x) = (\exists b \in \Z, e \in \N : e > 1 \ \text{and} \ b^e = x)$.
948 ///
949 /// # Worst-case complexity
950 /// $T(n) = O(n)$
951 ///
952 /// $M(n) = O(1)$
953 ///
954 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`: trial
955 /// division strips small prime factors, each division removing at least one bit, and a bounded
956 /// number of root extractions follow, each at worst $O(n)$.
957 ///
958 /// # Examples
959 /// See [here](super::is_power#is_power).
960 fn is_power(&self) -> bool {
961 if USIZE_IS_U32 {
962 is_power_u32(u32::wrapping_from(*self))
963 } else {
964 is_power_u64(u64::wrapping_from(*self))
965 }
966 }
967}
968
969macro_rules! impl_unsigned_32 {
970 ($t: ident) => {
971 impl ExpressAsPower for $t {
972 /// Expresses a number as a perfect power, if such a representation exists. We define a
973 /// perfect power as any number of the form $a^x$ where $x > 1$, with $a$ and $x$ both
974 /// integers. In particular, 0 and 1 are considered perfect powers. If a number has more
975 /// than one representation as a power, the representation with the smallest base is
976 /// returned. For example, $64=2^6=4^3=8^2$, but this function returns `(2,6)` rather
977 /// than `(4,3)` or `(8,2)`.
978 ///
979 /// # Worst-case complexity
980 /// $T(n) = O(n)$
981 ///
982 /// $M(n) = O(1)$
983 ///
984 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`:
985 /// trial division strips small prime factors, each division removing at least one bit,
986 /// and a bounded number of root extractions follow, each at worst $O(n)$.
987 ///
988 /// # Examples
989 /// See [here](super::is_power#express_as_power).
990 ///
991 /// # Notes
992 /// - This returns an [`Option`] which is either `Some((base, exp))` if the input is a
993 /// perfect power equal to $\text{base}^\text{exp}$, otherwise `None`.
994 /// - For 0 this returns `Some((0, 2))` and for 1 this returns `Some((1, 2))`.
995 fn express_as_power(&self) -> Option<($t, u64)> {
996 match express_as_power_u32(u32::from(*self)) {
997 Some((base, exp)) => Some(($t::exact_from(base), exp)),
998 _ => None,
999 }
1000 }
1001 }
1002
1003 impl IsPower for $t {
1004 /// Determines whether an integer is a perfect power. We define a perfect power as any
1005 /// number of the form $a^x$ where $x > 1$, with $a$ and $x$ both integers. In
1006 /// particular 0 and 1 are considered perfect powers.
1007 ///
1008 /// $f(x) = (\exists b \in \Z, e \in \N : e > 1 \ \text{and} \ b^e = x)$.
1009 ///
1010 /// # Worst-case complexity
1011 /// $T(n) = O(n)$
1012 ///
1013 /// $M(n) = O(1)$
1014 ///
1015 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`:
1016 /// trial division strips small prime factors, each division removing at least one bit,
1017 /// and a bounded number of root extractions follow, each at worst $O(n)$.
1018 ///
1019 /// # Examples
1020 /// See [here](super::is_power#is_power).
1021 #[inline]
1022 fn is_power(&self) -> bool {
1023 is_power_u32(u32::from(*self))
1024 }
1025 }
1026 };
1027}
1028impl_unsigned_32!(u8);
1029impl_unsigned_32!(u16);
1030impl_unsigned_32!(u32);
1031
1032impl ExpressAsPower for i64 {
1033 /// Expresses a number as a perfect power, if such a representation exists. We define a perfect
1034 /// power as any number of the form $a^x$ where $x > 1$, with $a$ and $x$ both integers. In
1035 /// particular, 0 and 1 are considered perfect powers. If a number has more than one
1036 /// representation as a power, the representation with the smallest base is returned. For
1037 /// example, $64=2^6=4^3=8^2$, but this function returns `(2,6)` rather than `(4,3)` or `(8,2)`.
1038 ///
1039 /// # Worst-case complexity
1040 /// $T(n) = O(n)$
1041 ///
1042 /// $M(n) = O(1)$
1043 ///
1044 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`: trial
1045 /// division strips small prime factors, each division removing at least one bit, and a bounded
1046 /// number of root extractions follow, each at worst $O(n)$.
1047 ///
1048 /// # Examples
1049 /// See [here](super::is_power#express_as_power).
1050 ///
1051 /// # Notes
1052 /// - This returns an [`Option`] which is either `Some((base, exp))` if the input is a perfect
1053 /// power equal to $\text{base}^\text{exp}$, otherwise `None`.
1054 /// - For 0 this returns `Some((0, 2))` and for 1 this returns `Some((1, 2))`.
1055 #[inline]
1056 fn express_as_power(&self) -> Option<(Self, u64)> {
1057 express_as_power_i64(*self)
1058 }
1059}
1060
1061impl ExpressAsPower for i128 {
1062 /// Expresses a number as a perfect power, if such a representation exists. We define a perfect
1063 /// power as any number of the form $a^x$ where $x > 1$, with $a$ and $x$ both integers. In
1064 /// particular, 0 and 1 are considered perfect powers. If a number has more than one
1065 /// representation as a power, the representation with the smallest base is returned. For
1066 /// example, $64=2^6=4^3=8^2$, but this function returns `(2,6)` rather than `(4,3)` or `(8,2)`.
1067 ///
1068 /// # Worst-case complexity
1069 /// $T(n) = O(n)$
1070 ///
1071 /// $M(n) = O(1)$
1072 ///
1073 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`: trial
1074 /// division strips small prime factors, each division removing at least one bit, and a bounded
1075 /// number of root extractions follow, each at worst $O(n)$.
1076 ///
1077 /// # Examples
1078 /// See [here](super::is_power#express_as_power).
1079 ///
1080 /// # Notes
1081 /// - This returns an [`Option`] which is either `Some((base, exp))` if the input is a perfect
1082 /// power equal to $\text{base}^\text{exp}$, otherwise `None`.
1083 /// - For 0 this returns `Some((0, 2))` and for 1 this returns `Some((1, 2))`.
1084 #[inline]
1085 fn express_as_power(&self) -> Option<(Self, u64)> {
1086 express_as_power_i128(*self)
1087 }
1088}
1089
1090impl ExpressAsPower for isize {
1091 /// Expresses a number as a perfect power, if such a representation exists. We define a perfect
1092 /// power as any number of the form $a^x$ where $x > 1$, with $a$ and $x$ both integers. In
1093 /// particular, 0 and 1 are considered perfect powers. If a number has more than one
1094 /// representation as a power, the representation with the smallest base is returned. For
1095 /// example, $64=2^6=4^3=8^2$, but this function returns `(2,6)` rather than `(4,3)` or `(8,2)`.
1096 ///
1097 /// # Worst-case complexity
1098 /// $T(n) = O(n)$
1099 ///
1100 /// $M(n) = O(1)$
1101 ///
1102 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`: trial
1103 /// division strips small prime factors, each division removing at least one bit, and a bounded
1104 /// number of root extractions follow, each at worst $O(n)$.
1105 ///
1106 /// # Examples
1107 /// See [here](super::is_power#express_as_power).
1108 ///
1109 /// # Notes
1110 /// - This returns an [`Option`] which is either `Some((base, exp))` if the input is a perfect
1111 /// power equal to $\text{base}^\text{exp}$, otherwise `None`.
1112 /// - For 0 this returns `Some((0, 2))` and for 1 this returns `Some((1, 2))`.
1113 fn express_as_power(&self) -> Option<(Self, u64)> {
1114 if USIZE_IS_U32 {
1115 match express_as_power_i32(i32::wrapping_from(*self)) {
1116 Some((base, exp)) => Some((Self::wrapping_from(base), exp)),
1117 _ => None,
1118 }
1119 } else {
1120 match express_as_power_i64(i64::wrapping_from(*self)) {
1121 Some((base, exp)) => Some((Self::wrapping_from(base), exp)),
1122 _ => None,
1123 }
1124 }
1125 }
1126}
1127
1128impl IsPower for i64 {
1129 /// Determines whether an integer is a perfect power. We define a perfect power as any number of
1130 /// the form $a^x$ where $x > 1$, with $a$ and $x$ both integers. In particular 0 and 1 are
1131 /// considered perfect powers.
1132 ///
1133 /// $f(x) = (\exists b \in \Z, e \in \N : e > 1 \ \text{and} \ b^e = x)$.
1134 ///
1135 /// # Worst-case complexity
1136 /// $T(n) = O(n)$
1137 ///
1138 /// $M(n) = O(1)$
1139 ///
1140 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`: trial
1141 /// division strips small prime factors, each division removing at least one bit, and a bounded
1142 /// number of root extractions follow, each at worst $O(n)$.
1143 ///
1144 /// # Examples
1145 /// See [here](super::is_power#is_power).
1146 #[inline]
1147 fn is_power(&self) -> bool {
1148 is_power_i64(*self)
1149 }
1150}
1151
1152impl IsPower for i128 {
1153 /// Determines whether an integer is a perfect power. We define a perfect power as any number of
1154 /// the form $a^x$ where $x > 1$, with $a$ and $x$ both integers. In particular 0 and 1 are
1155 /// considered perfect powers.
1156 ///
1157 /// $f(x) = (\exists b \in \Z, e \in \N : e > 1 \ \text{and} \ b^e = x)$.
1158 ///
1159 /// # Worst-case complexity
1160 /// $T(n) = O(n)$
1161 ///
1162 /// $M(n) = O(1)$
1163 ///
1164 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`: trial
1165 /// division strips small prime factors, each division removing at least one bit, and a bounded
1166 /// number of root extractions follow, each at worst $O(n)$.
1167 ///
1168 /// # Examples
1169 /// See [here](super::is_power#is_power).
1170 #[inline]
1171 fn is_power(&self) -> bool {
1172 is_power_i128(*self)
1173 }
1174}
1175
1176impl IsPower for isize {
1177 /// Determines whether an integer is a perfect power. We define a perfect power as any number of
1178 /// the form $a^x$ where $x > 1$, with $a$ and $x$ both integers. In particular 0 and 1 are
1179 /// considered perfect powers.
1180 ///
1181 /// $f(x) = (\exists b \in \Z, e \in \N : e > 1 \ \text{and} \ b^e = x)$.
1182 ///
1183 /// # Worst-case complexity
1184 /// $T(n) = O(n)$
1185 ///
1186 /// $M(n) = O(1)$
1187 ///
1188 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`: trial
1189 /// division strips small prime factors, each division removing at least one bit, and a bounded
1190 /// number of root extractions follow, each at worst $O(n)$.
1191 ///
1192 /// # Examples
1193 /// See [here](super::is_power#is_power).
1194 fn is_power(&self) -> bool {
1195 if USIZE_IS_U32 {
1196 is_power_i32(i32::wrapping_from(*self))
1197 } else {
1198 is_power_i64(i64::wrapping_from(*self))
1199 }
1200 }
1201}
1202
1203macro_rules! impl_signed_32 {
1204 ($t: ident) => {
1205 impl ExpressAsPower for $t {
1206 /// Expresses a number as a perfect power, if such a representation exists. We define a
1207 /// perfect power as any number of the form $a^x$ where $x > 1$, with $a$ and $x$ both
1208 /// integers. In particular, 0 and 1 are considered perfect powers. If a number has more
1209 /// than one representation as a power, the representation with the smallest base is
1210 /// returned. For example, $64=2^6=4^3=8^2$, but this function returns `(2,6)` rather
1211 /// than `(4,3)` or `(8,2)`.
1212 ///
1213 /// # Worst-case complexity
1214 /// $T(n) = O(n)$
1215 ///
1216 /// $M(n) = O(1)$
1217 ///
1218 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`:
1219 /// trial division strips small prime factors, each division removing at least one bit,
1220 /// and a bounded number of root extractions follow, each at worst $O(n)$.
1221 ///
1222 /// # Examples
1223 /// See [here](super::is_power#express_as_power).
1224 ///
1225 /// # Notes
1226 /// - This returns an [`Option`] which is either `Some((base, exp))` if the input is a
1227 /// perfect power equal to $\text{base}^\text{exp}$, otherwise `None`.
1228 /// - For 0 this returns `Some((0, 2))` and for 1 this returns `Some((1, 2))`.
1229 fn express_as_power(&self) -> Option<($t, u64)> {
1230 match express_as_power_i32(i32::from(*self)) {
1231 Some((base, exp)) => Some(($t::exact_from(base), exp)),
1232 _ => None,
1233 }
1234 }
1235 }
1236
1237 impl IsPower for $t {
1238 /// Determines whether an integer is a perfect power. We define a perfect power as any
1239 /// number of the form $a^x$ where $x > 1$, with $a$ and $x$ both integers. In
1240 /// particular 0 and 1 are considered perfect powers.
1241 ///
1242 /// $f(x) = (\exists b \in \Z, e \in \N : e > 1 \ \text{and} \ b^e = x)$.
1243 ///
1244 /// # Worst-case complexity
1245 /// $T(n) = O(n)$
1246 ///
1247 /// $M(n) = O(1)$
1248 ///
1249 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`:
1250 /// trial division strips small prime factors, each division removing at least one bit,
1251 /// and a bounded number of root extractions follow, each at worst $O(n)$.
1252 ///
1253 /// # Examples
1254 /// See [here](super::is_power#is_power).
1255 #[inline]
1256 fn is_power(&self) -> bool {
1257 is_power_i32(i32::from(*self))
1258 }
1259 }
1260 };
1261}
1262impl_signed_32!(i8);
1263impl_signed_32!(i16);
1264impl_signed_32!(i32);