diff options
| author | bors <bors@rust-lang.org> | 2014-01-19 19:46:35 -0800 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-01-19 19:46:35 -0800 |
| commit | 764f2cb6f3517869e31fc7b93ff11dd840db8d30 (patch) | |
| tree | ad183f07bbaad8493d23db4d2fcc7f5263fa4aab /src/libstd/num | |
| parent | 0e6455e2b8ee707c0683c67ba224b7682aff4e85 (diff) | |
| parent | 3830a3b4f2559165a89847320d277ef827dd1da9 (diff) | |
| download | rust-764f2cb6f3517869e31fc7b93ff11dd840db8d30.tar.gz rust-764f2cb6f3517869e31fc7b93ff11dd840db8d30.zip | |
auto merge of #11649 : FlaPer87/rust/pow, r=cmr
There was an old and barely used implementation of pow, which expected
both parameters to be uint and required more traits to be implemented.
Since a new implementation for `pow` landed, I'm proposing to remove
this old impl in favor of the new one.
The benchmark shows that the new implementation is faster than the one being removed:
```
test num::bench::bench_pow_function ..bench: 9429 ns/iter (+/- 2055)
test num::bench::bench_pow_with_uint_function ...bench: 28476 ns/iter (+/- 2202)
```
Diffstat (limited to 'src/libstd/num')
| -rw-r--r-- | src/libstd/num/mod.rs | 46 | ||||
| -rw-r--r-- | src/libstd/num/strconv.rs | 13 |
2 files changed, 22 insertions, 37 deletions
diff --git a/src/libstd/num/mod.rs b/src/libstd/num/mod.rs index bdbf0344b47..c374d6c2157 100644 --- a/src/libstd/num/mod.rs +++ b/src/libstd/num/mod.rs @@ -993,37 +993,6 @@ pub fn from_str_radix<T: FromStrRadix>(str: &str, radix: uint) -> Option<T> { FromStrRadix::from_str_radix(str, radix) } -/// Calculates a power to a given radix, optimized for uint `pow` and `radix`. -/// -/// Returns `radix^pow` as `T`. -/// -/// Note: -/// Also returns `1` for `0^0`, despite that technically being an -/// undefined number. The reason for this is twofold: -/// - If code written to use this function cares about that special case, it's -/// probably going to catch it before making the call. -/// - If code written to use this function doesn't care about it, it's -/// probably assuming that `x^0` always equals `1`. -/// -pub fn pow_with_uint<T:NumCast+One+Zero+Div<T,T>+Mul<T,T>>(radix: uint, pow: uint) -> T { - let _0: T = Zero::zero(); - let _1: T = One::one(); - - if pow == 0u { return _1; } - if radix == 0u { return _0; } - let mut my_pow = pow; - let mut total = _1; - let mut multiplier = cast(radix).unwrap(); - while (my_pow > 0u) { - if my_pow % 2u == 1u { - total = total * multiplier; - } - my_pow = my_pow / 2u; - multiplier = multiplier * multiplier; - } - total -} - impl<T: Zero + 'static> Zero for @T { fn zero() -> @T { @Zero::zero() } fn is_zero(&self) -> bool { (**self).is_zero() } @@ -1684,3 +1653,18 @@ mod tests { assert_pow(2u64, 50); } } + + +#[cfg(test)] +mod bench { + use num; + use vec; + use prelude::*; + use extra::test::BenchHarness; + + #[bench] + fn bench_pow_function(b: &mut BenchHarness) { + let v = vec::from_fn(1024, |n| n); + b.iter(|| {v.iter().fold(0, |old, new| num::pow(old, *new));}); + } +} diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs index ba51ac3e88d..0c41c538c6c 100644 --- a/src/libstd/num/strconv.rs +++ b/src/libstd/num/strconv.rs @@ -20,7 +20,8 @@ use str::{StrSlice}; use str; use vec::{CopyableVector, ImmutableVector, MutableVector}; use vec::OwnedVector; -use num::{NumCast, Zero, One, cast, pow_with_uint, Integer}; +use num; +use num::{NumCast, Zero, One, cast, Integer}; use num::{Round, Float, FPNaN, FPInfinite, ToPrimitive}; pub enum ExponentFormat { @@ -648,10 +649,10 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Div<T,T>+ if exp_found { let c = buf[i] as char; - let base = match (c, exponent) { + let base: T = match (c, exponent) { // c is never _ so don't need to handle specially - ('e', ExpDec) | ('E', ExpDec) => 10u, - ('p', ExpBin) | ('P', ExpBin) => 2u, + ('e', ExpDec) | ('E', ExpDec) => cast(10u).unwrap(), + ('p', ExpBin) | ('P', ExpBin) => cast(2u).unwrap(), _ => return None // char doesn't fit given exponent format }; @@ -664,9 +665,9 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Div<T,T>+ match exp { Some(exp_pow) => { multiplier = if exp_pow < 0 { - _1 / pow_with_uint::<T>(base, (-exp_pow.to_int().unwrap()) as uint) + _1 / num::pow(base, (-exp_pow.to_int().unwrap()) as uint) } else { - pow_with_uint::<T>(base, exp_pow.to_int().unwrap() as uint) + num::pow(base, exp_pow.to_int().unwrap() as uint) } } None => return None // invalid exponent -> invalid number |
