Skip to content

Commit 943c02c

Browse files
committed
refactor: Increase test coverage for pow
Increase test coverage to check all interesting edge cases and all variants.
1 parent 616f71d commit 943c02c

2 files changed

Lines changed: 306 additions & 34 deletions

File tree

library/coretests/tests/num/int_macros.rs

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

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

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

346516
{
347-
// test for negative exponent.
348-
const R: $T = -2;
349-
assert_eq_const_safe!($T: R.pow(2), 4 as $T);
350-
assert_eq_const_safe!($T: R.pow(3), -8 as $T);
351-
assert_eq_const_safe!($T: R.pow(0), 1 as $T);
352-
assert_eq_const_safe!($T: R.wrapping_pow(2), 4 as $T);
353-
assert_eq_const_safe!($T: R.wrapping_pow(3), -8 as $T);
517+
const R: $T = $T::MIN;
354518
assert_eq_const_safe!($T: R.wrapping_pow(0), 1 as $T);
355-
assert_eq_const_safe!(Option<$T>: R.checked_pow(2), Some(4 as $T));
356-
assert_eq_const_safe!(Option<$T>: R.checked_pow(3), Some(-8 as $T));
519+
assert_eq_const_safe!($T: R.wrapping_pow(1), R as $T);
520+
assert_eq_const_safe!($T: R.wrapping_pow(2), 0 as $T);
521+
assert_eq_const_safe!($T: R.wrapping_pow(128), 0 as $T);
522+
assert_eq_const_safe!($T: R.wrapping_pow(129), 0 as $T);
523+
357524
assert_eq_const_safe!(Option<$T>: R.checked_pow(0), Some(1 as $T));
358-
assert_eq_const_safe!(($T, bool): R.overflowing_pow(2), (4 as $T, false));
359-
assert_eq_const_safe!(($T, bool): R.overflowing_pow(3), (-8 as $T, false));
525+
assert_eq_const_safe!(Option<$T>: R.checked_pow(1), Some(R as $T));
526+
assert_eq_const_safe!(Option<$T>: R.checked_pow(2), None);
527+
assert_eq_const_safe!(Option<$T>: R.checked_pow(128), None);
528+
assert_eq_const_safe!(Option<$T>: R.checked_pow(129), None);
529+
360530
assert_eq_const_safe!(($T, bool): R.overflowing_pow(0), (1 as $T, false));
361-
assert_eq_const_safe!($T: R.saturating_pow(2), 4 as $T);
362-
assert_eq_const_safe!($T: R.saturating_pow(3), -8 as $T);
531+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(1), (R as $T, false));
532+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(2), (0 as $T, true));
533+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(128), (0 as $T, true));
534+
assert_eq_const_safe!(($T, bool): R.overflowing_pow(129), (0 as $T, true));
535+
363536
assert_eq_const_safe!($T: R.saturating_pow(0), 1 as $T);
537+
assert_eq_const_safe!($T: R.saturating_pow(1), R as $T);
538+
assert_eq_const_safe!($T: R.saturating_pow(2), $T::MAX);
539+
assert_eq_const_safe!($T: R.saturating_pow(128), $T::MAX);
540+
assert_eq_const_safe!($T: R.saturating_pow(129), $T::MIN);
364541
}
365542
}
366543

0 commit comments

Comments
 (0)