From 043a5b2918edcba7147c7f518cd142bdb5960ee5 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Sat, 7 Mar 2015 14:12:50 -0800 Subject: [PATCH] pow: avoid unnecessary overflows The code was performing an extra squaring of the base, which might trigger an arithmetic overflow that doesn't matter to the result. Now this squaring is only attempted when enough exp remains to need it. A new doctest tries pow(6u8, 3), where an extra square would exceed 256. --- src/lib.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 4ce15d3..8f5ffa1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -121,7 +121,8 @@ pub fn abs_sub(x: T, y: T) -> T { /// ```rust /// use num; /// -/// assert_eq!(num::pow(2i, 4), 16); +/// assert_eq!(num::pow(2i8, 4), 16); +/// assert_eq!(num::pow(6u8, 3), 216); /// ``` #[inline] pub fn pow>(mut base: T, mut exp: usize) -> T { @@ -132,7 +133,11 @@ pub fn pow>(mut base: T, mut exp: usize) -> if (exp & 1) == 1 { acc = acc * base.clone(); } - base = base.clone() * base; + + // avoid overflow if we won't need it + if exp > 1 { + base = base.clone() * base; + } exp = exp >> 1; } acc