Skip to content

Commit 2395dba

Browse files
committed
refactor: Increase test coverage for pow
Increase test coverage to check all interesting edge cases and all variants.
1 parent 9726f4d commit 2395dba

File tree

2 files changed

+307
-35
lines changed

2 files changed

+307
-35
lines changed

library/coretests/tests/num/int_macros.rs

Lines changed: 201 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -316,50 +316,227 @@ macro_rules! int_module {
316316
}
317317

318318
fn test_pow() {
319+
{
320+
const R: $T = 0;
321+
assert_eq_const_safe!($T: R.wrapping_pow(0), 1 as $T);
322+
assert_eq_const_safe!($T: R.wrapping_pow(1), 0 as $T);
323+
assert_eq_const_safe!($T: R.wrapping_pow(2), 0 as $T);
324+
assert_eq_const_safe!($T: R.wrapping_pow(128), 0 as $T);
325+
assert_eq_const_safe!($T: R.wrapping_pow(129), 0 as $T);
326+
327+
assert_eq_const_safe!(Option<$T>: R.checked_pow(0), Some(1 as $T));
328+
assert_eq_const_safe!(Option<$T>: R.checked_pow(1), Some(0 as $T));
329+
assert_eq_const_safe!(Option<$T>: R.checked_pow(2), Some(0 as $T));
330+
assert_eq_const_safe!(Option<$T>: R.checked_pow(128), Some(0 as $T));
331+
assert_eq_const_safe!(Option<$T>: R.checked_pow(129), Some(0 as $T));
332+
333+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(0), (1 as $T, false));
334+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(1), (0 as $T, false));
335+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(2), (0 as $T, false));
336+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(128), (0 as $T, false));
337+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(129), (0 as $T, false));
338+
339+
assert_eq_const_safe!($T: R.saturating_pow(0), 1 as $T);
340+
assert_eq_const_safe!($T: R.saturating_pow(1), 0 as $T);
341+
assert_eq_const_safe!($T: R.saturating_pow(2), 0 as $T);
342+
assert_eq_const_safe!($T: R.saturating_pow(128), 0 as $T);
343+
assert_eq_const_safe!($T: R.saturating_pow(129), 0 as $T);
344+
}
345+
346+
{
347+
const R: $T = 1;
348+
assert_eq_const_safe!($T: R.wrapping_pow(0), 1 as $T);
349+
assert_eq_const_safe!($T: R.wrapping_pow(1), 1 as $T);
350+
assert_eq_const_safe!($T: R.wrapping_pow(2), 1 as $T);
351+
assert_eq_const_safe!($T: R.wrapping_pow(128), 1 as $T);
352+
assert_eq_const_safe!($T: R.wrapping_pow(129), 1 as $T);
353+
354+
assert_eq_const_safe!(Option<$T>: R.checked_pow(0), Some(1 as $T));
355+
assert_eq_const_safe!(Option<$T>: R.checked_pow(1), Some(1 as $T));
356+
assert_eq_const_safe!(Option<$T>: R.checked_pow(2), Some(1 as $T));
357+
assert_eq_const_safe!(Option<$T>: R.checked_pow(128), Some(1 as $T));
358+
assert_eq_const_safe!(Option<$T>: R.checked_pow(129), Some(1 as $T));
359+
360+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(0), (1 as $T, false));
361+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(1), (1 as $T, false));
362+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(2), (1 as $T, false));
363+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(128), (1 as $T, false));
364+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(129), (1 as $T, false));
365+
366+
assert_eq_const_safe!($T: R.saturating_pow(0), 1 as $T);
367+
assert_eq_const_safe!($T: R.saturating_pow(1), 1 as $T);
368+
assert_eq_const_safe!($T: R.saturating_pow(2), 1 as $T);
369+
assert_eq_const_safe!($T: R.saturating_pow(128), 1 as $T);
370+
assert_eq_const_safe!($T: R.saturating_pow(129), 1 as $T);
371+
}
372+
373+
{
374+
const R: $T = -1;
375+
assert_eq_const_safe!($T: R.wrapping_pow(0), 1 as $T);
376+
assert_eq_const_safe!($T: R.wrapping_pow(1), -1 as $T);
377+
assert_eq_const_safe!($T: R.wrapping_pow(2), 1 as $T);
378+
assert_eq_const_safe!($T: R.wrapping_pow(128), 1 as $T);
379+
assert_eq_const_safe!($T: R.wrapping_pow(129), -1 as $T);
380+
381+
assert_eq_const_safe!(Option<$T>: R.checked_pow(0), Some(1 as $T));
382+
assert_eq_const_safe!(Option<$T>: R.checked_pow(1), Some(-1 as $T));
383+
assert_eq_const_safe!(Option<$T>: R.checked_pow(2), Some(1 as $T));
384+
assert_eq_const_safe!(Option<$T>: R.checked_pow(128), Some(1 as $T));
385+
assert_eq_const_safe!(Option<$T>: R.checked_pow(129), Some(-1 as $T));
386+
387+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(0), (1 as $T, false));
388+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(1), (-1 as $T, false));
389+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(2), (1 as $T, false));
390+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(128), (1 as $T, false));
391+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(129), (-1 as $T, false));
392+
393+
assert_eq_const_safe!($T: R.saturating_pow(0), 1 as $T);
394+
assert_eq_const_safe!($T: R.saturating_pow(1), -1 as $T);
395+
assert_eq_const_safe!($T: R.saturating_pow(2), 1 as $T);
396+
assert_eq_const_safe!($T: R.saturating_pow(128), 1 as $T);
397+
assert_eq_const_safe!($T: R.saturating_pow(129), -1 as $T);
398+
}
399+
319400
{
320401
const R: $T = 2;
321-
assert_eq_const_safe!($T: R.pow(2), 4 as $T);
322-
assert_eq_const_safe!($T: R.pow(0), 1 as $T);
323-
assert_eq_const_safe!($T: R.wrapping_pow(2), 4 as $T);
324402
assert_eq_const_safe!($T: R.wrapping_pow(0), 1 as $T);
325-
assert_eq_const_safe!(Option<$T>: R.checked_pow(2), Some(4 as $T));
403+
assert_eq_const_safe!($T: R.wrapping_pow(1), 2 as $T);
404+
assert_eq_const_safe!($T: R.wrapping_pow(2), 4 as $T);
405+
assert_eq_const_safe!($T: R.wrapping_pow(128), 0 as $T);
406+
assert_eq_const_safe!($T: R.wrapping_pow(129), 0 as $T);
407+
326408
assert_eq_const_safe!(Option<$T>: R.checked_pow(0), Some(1 as $T));
327-
assert_eq_const_safe!(($T, bool): R.overflowing_pow(2), (4 as $T, false));
409+
assert_eq_const_safe!(Option<$T>: R.checked_pow(1), Some(2 as $T));
410+
assert_eq_const_safe!(Option<$T>: R.checked_pow(2), Some(4 as $T));
411+
assert_eq_const_safe!(Option<$T>: R.checked_pow(128), None);
412+
assert_eq_const_safe!(Option<$T>: R.checked_pow(129), None);
413+
328414
assert_eq_const_safe!(($T, bool): R.overflowing_pow(0), (1 as $T, false));
415+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(1), (2 as $T, false));
416+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(2), (4 as $T, false));
417+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(128), (0 as $T, true));
418+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(129), (0 as $T, true));
419+
420+
assert_eq_const_safe!($T: R.saturating_pow(0), 1 as $T);
421+
assert_eq_const_safe!($T: R.saturating_pow(1), 2 as $T);
329422
assert_eq_const_safe!($T: R.saturating_pow(2), 4 as $T);
423+
assert_eq_const_safe!($T: R.saturating_pow(128), $T::MAX);
424+
assert_eq_const_safe!($T: R.saturating_pow(129), $T::MAX);
425+
}
426+
427+
{
428+
const R: $T = -2;
429+
assert_eq_const_safe!($T: R.wrapping_pow(0), 1 as $T);
430+
assert_eq_const_safe!($T: R.wrapping_pow(1), -2 as $T);
431+
assert_eq_const_safe!($T: R.wrapping_pow(2), 4 as $T);
432+
assert_eq_const_safe!($T: R.wrapping_pow($T::BITS - 1), $T::MIN);
433+
assert_eq_const_safe!($T: R.wrapping_pow($T::BITS), 0 as $T);
434+
assert_eq_const_safe!($T: R.wrapping_pow($T::BITS + 1), 0 as $T);
435+
assert_eq_const_safe!($T: R.wrapping_pow(128), 0 as $T);
436+
assert_eq_const_safe!($T: R.wrapping_pow(129), 0 as $T);
437+
438+
assert_eq_const_safe!(Option<$T>: R.checked_pow(0), Some(1 as $T));
439+
assert_eq_const_safe!(Option<$T>: R.checked_pow(1), Some(-2 as $T));
440+
assert_eq_const_safe!(Option<$T>: R.checked_pow(2), Some(4 as $T));
441+
assert_eq_const_safe!(Option<$T>: R.checked_pow($T::BITS - 1), Some($T::MIN));
442+
assert_eq_const_safe!(Option<$T>: R.checked_pow($T::BITS), None);
443+
assert_eq_const_safe!(Option<$T>: R.checked_pow($T::BITS + 1), None);
444+
assert_eq_const_safe!(Option<$T>: R.checked_pow(128), None);
445+
assert_eq_const_safe!(Option<$T>: R.checked_pow(129), None);
446+
447+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(0), (1 as $T, false));
448+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(1), (-2 as $T, false));
449+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(2), (4 as $T, false));
450+
assert_eq_const_safe!(($T, bool): R.overflowing_pow($T::BITS - 1), ($T::MIN, false));
451+
assert_eq_const_safe!(($T, bool): R.overflowing_pow($T::BITS), (0 as $T, true));
452+
assert_eq_const_safe!(($T, bool): R.overflowing_pow($T::BITS + 1), (0 as $T, true));
453+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(128), (0 as $T, true));
454+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(129), (0 as $T, true));
455+
330456
assert_eq_const_safe!($T: R.saturating_pow(0), 1 as $T);
457+
assert_eq_const_safe!($T: R.saturating_pow(1), -2 as $T);
458+
assert_eq_const_safe!($T: R.saturating_pow(2), 4 as $T);
459+
assert_eq_const_safe!($T: R.saturating_pow($T::BITS - 1), $T::MIN);
460+
assert_eq_const_safe!($T: R.saturating_pow($T::BITS), $T::MAX);
461+
assert_eq_const_safe!($T: R.saturating_pow($T::BITS + 1), $T::MIN);
462+
assert_eq_const_safe!($T: R.saturating_pow(128), $T::MAX);
463+
assert_eq_const_safe!($T: R.saturating_pow(129), $T::MIN);
464+
}
465+
466+
// Overflow in the shift caclculation should result in the final
467+
// result being 0 rather than accidentally succeeding due to a
468+
// shift within the word size.
469+
// eg `4 ** 0x8000_0000` should give 0 rather than 1 << 0
470+
{
471+
const R: $T = 4;
472+
const HALF: u32 = u32::MAX / 2 + 1;
473+
assert_eq_const_safe!($T: R.wrapping_pow(HALF), 0 as $T);
474+
assert_eq_const_safe!(Option<$T>: R.checked_pow(HALF), None);
475+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(HALF), (0 as $T, true));
476+
assert_eq_const_safe!($T: R.saturating_pow(HALF), $T::MAX);
331477
}
332478

333479
{
334-
const R: $T = MAX;
335-
// use `^` to represent .pow() with no overflow.
336-
// if itest::MAX == 2^j-1, then itest is a `j` bit int,
337-
// so that `itest::MAX*itest::MAX == 2^(2*j)-2^(j+1)+1`,
338-
// thussaturating_pow the overflowing result is exactly 1.
480+
const R: $T = -4;
481+
const HALF: u32 = u32::MAX / 2 + 1;
482+
assert_eq_const_safe!($T: R.wrapping_pow(HALF), 0 as $T);
483+
assert_eq_const_safe!(Option<$T>: R.checked_pow(HALF), None);
484+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(HALF), (0 as $T, true));
485+
assert_eq_const_safe!($T: R.saturating_pow(HALF), $T::MAX);
486+
}
487+
488+
{
489+
const R: $T = $T::MAX;
490+
assert_eq_const_safe!($T: R.wrapping_pow(0), 1 as $T);
491+
assert_eq_const_safe!($T: R.wrapping_pow(1), R as $T);
339492
assert_eq_const_safe!($T: R.wrapping_pow(2), 1 as $T);
493+
assert_eq_const_safe!($T: R.wrapping_pow(128), 1 as $T);
494+
assert_eq_const_safe!($T: R.wrapping_pow(129), R as $T);
495+
496+
assert_eq_const_safe!(Option<$T>: R.checked_pow(0), Some(1 as $T));
497+
assert_eq_const_safe!(Option<$T>: R.checked_pow(1), Some(R as $T));
340498
assert_eq_const_safe!(Option<$T>: R.checked_pow(2), None);
499+
assert_eq_const_safe!(Option<$T>: R.checked_pow(128), None);
500+
assert_eq_const_safe!(Option<$T>: R.checked_pow(129), None);
501+
502+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(0), (1 as $T, false));
503+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(1), (R as $T, false));
341504
assert_eq_const_safe!(($T, bool): R.overflowing_pow(2), (1 as $T, true));
342-
assert_eq_const_safe!($T: R.saturating_pow(2), MAX);
505+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(128), (1 as $T, true));
506+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(129), (R as $T, true));
507+
508+
assert_eq_const_safe!($T: R.saturating_pow(0), 1 as $T);
509+
assert_eq_const_safe!($T: R.saturating_pow(1), R as $T);
510+
assert_eq_const_safe!($T: R.saturating_pow(2), $T::MAX);
511+
assert_eq_const_safe!($T: R.saturating_pow(128), $T::MAX);
512+
assert_eq_const_safe!($T: R.saturating_pow(129), $T::MAX);
343513
}
344514

345515
{
346-
// test for negative exponent.
347-
const R: $T = -2;
348-
assert_eq_const_safe!($T: R.pow(2), 4 as $T);
349-
assert_eq_const_safe!($T: R.pow(3), -8 as $T);
350-
assert_eq_const_safe!($T: R.pow(0), 1 as $T);
351-
assert_eq_const_safe!($T: R.wrapping_pow(2), 4 as $T);
352-
assert_eq_const_safe!($T: R.wrapping_pow(3), -8 as $T);
516+
const R: $T = $T::MIN;
353517
assert_eq_const_safe!($T: R.wrapping_pow(0), 1 as $T);
354-
assert_eq_const_safe!(Option<$T>: R.checked_pow(2), Some(4 as $T));
355-
assert_eq_const_safe!(Option<$T>: R.checked_pow(3), Some(-8 as $T));
518+
assert_eq_const_safe!($T: R.wrapping_pow(1), R as $T);
519+
assert_eq_const_safe!($T: R.wrapping_pow(2), 0 as $T);
520+
assert_eq_const_safe!($T: R.wrapping_pow(128), 0 as $T);
521+
assert_eq_const_safe!($T: R.wrapping_pow(129), 0 as $T);
522+
356523
assert_eq_const_safe!(Option<$T>: R.checked_pow(0), Some(1 as $T));
357-
assert_eq_const_safe!(($T, bool): R.overflowing_pow(2), (4 as $T, false));
358-
assert_eq_const_safe!(($T, bool): R.overflowing_pow(3), (-8 as $T, false));
524+
assert_eq_const_safe!(Option<$T>: R.checked_pow(1), Some(R as $T));
525+
assert_eq_const_safe!(Option<$T>: R.checked_pow(2), None);
526+
assert_eq_const_safe!(Option<$T>: R.checked_pow(128), None);
527+
assert_eq_const_safe!(Option<$T>: R.checked_pow(129), None);
528+
359529
assert_eq_const_safe!(($T, bool): R.overflowing_pow(0), (1 as $T, false));
360-
assert_eq_const_safe!($T: R.saturating_pow(2), 4 as $T);
361-
assert_eq_const_safe!($T: R.saturating_pow(3), -8 as $T);
530+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(1), (R as $T, false));
531+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(2), (0 as $T, true));
532+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(128), (0 as $T, true));
533+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(129), (0 as $T, true));
534+
362535
assert_eq_const_safe!($T: R.saturating_pow(0), 1 as $T);
536+
assert_eq_const_safe!($T: R.saturating_pow(1), R as $T);
537+
assert_eq_const_safe!($T: R.saturating_pow(2), $T::MAX);
538+
assert_eq_const_safe!($T: R.saturating_pow(128), $T::MAX);
539+
assert_eq_const_safe!($T: R.saturating_pow(129), $T::MIN);
363540
}
364541
}
365542

0 commit comments

Comments
 (0)