diff --git a/doc/guide-tasks.md b/doc/guide-tasks.md index 80261314d2a..746e7f065cc 100644 --- a/doc/guide-tasks.md +++ b/doc/guide-tasks.md @@ -290,7 +290,7 @@ be distributed on the available cores. fn partial_sum(start: uint) -> f64 { let mut local_sum = 0f64; for num in range(start*100000, (start+1)*100000) { - local_sum += (num as f64 + 1.0).pow(&-2.0); + local_sum += (num as f64 + 1.0).powf(&-2.0); } local_sum } @@ -326,7 +326,7 @@ a single large vector of floats. Each task needs the full vector to perform its use extra::arc::Arc; fn pnorm(nums: &~[f64], p: uint) -> f64 { - nums.iter().fold(0.0, |a,b| a+(*b).pow(&(p as f64)) ).pow(&(1.0 / (p as f64))) + nums.iter().fold(0.0, |a,b| a+(*b).powf(&(p as f64)) ).powf(&(1.0 / (p as f64))) } fn main() { diff --git a/src/libextra/num/rational.rs b/src/libextra/num/rational.rs index 4edccf685e2..c5b405a45aa 100644 --- a/src/libextra/num/rational.rs +++ b/src/libextra/num/rational.rs @@ -653,19 +653,19 @@ fn test(given: T, (numer, denom): (&str, &str)) { // f32 test(3.14159265359f32, ("13176795", "4194304")); - test(2f32.pow(&100.), ("1267650600228229401496703205376", "1")); - test(-2f32.pow(&100.), ("-1267650600228229401496703205376", "1")); - test(1.0 / 2f32.pow(&100.), ("1", "1267650600228229401496703205376")); + test(2f32.powf(&100.), ("1267650600228229401496703205376", "1")); + test(-2f32.powf(&100.), ("-1267650600228229401496703205376", "1")); + test(1.0 / 2f32.powf(&100.), ("1", "1267650600228229401496703205376")); test(684729.48391f32, ("1369459", "2")); test(-8573.5918555f32, ("-4389679", "512")); // f64 test(3.14159265359f64, ("3537118876014453", "1125899906842624")); - test(2f64.pow(&100.), ("1267650600228229401496703205376", "1")); - test(-2f64.pow(&100.), ("-1267650600228229401496703205376", "1")); + test(2f64.powf(&100.), ("1267650600228229401496703205376", "1")); + test(-2f64.powf(&100.), ("-1267650600228229401496703205376", "1")); test(684729.48391f64, ("367611342500051", "536870912")); test(-8573.5918555, ("-4713381968463931", "549755813888")); - test(1.0 / 2f64.pow(&100.), ("1", "1267650600228229401496703205376")); + test(1.0 / 2f64.powf(&100.), ("1", "1267650600228229401496703205376")); } #[test] diff --git a/src/libextra/stats.rs b/src/libextra/stats.rs index 1d57e94035a..de33060896f 100644 --- a/src/libextra/stats.rs +++ b/src/libextra/stats.rs @@ -349,8 +349,8 @@ pub fn write_boxplot(w: &mut io::Writer, s: &Summary, width_hint: uint) { let (q1,q2,q3) = s.quartiles; // the .abs() handles the case where numbers are negative - let lomag = (10.0_f64).pow(&(s.min.abs().log10().floor())); - let himag = (10.0_f64).pow(&(s.max.abs().log10().floor())); + let lomag = (10.0_f64).powf(&(s.min.abs().log10().floor())); + let himag = (10.0_f64).powf(&(s.max.abs().log10().floor())); // need to consider when the limit is zero let lo = if lomag == 0.0 { diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs index a8eaa895650..e77348268c7 100644 --- a/src/libstd/num/f32.rs +++ b/src/libstd/num/f32.rs @@ -409,7 +409,7 @@ fn ln_10() -> f32 { 2.30258509299404568401799145468436421 } fn recip(&self) -> f32 { 1.0 / *self } #[inline] - fn pow(&self, n: &f32) -> f32 { pow(*self, *n) } + fn powf(&self, n: &f32) -> f32 { pow(*self, *n) } #[inline] fn sqrt(&self) -> f32 { sqrt(*self) } @@ -1265,7 +1265,7 @@ fn test_frexp_nowin() { fn test_integer_decode() { assert_eq!(3.14159265359f32.integer_decode(), (13176795u64, -22i16, 1i8)); assert_eq!((-8573.5918555f32).integer_decode(), (8779358u64, -10i16, -1i8)); - assert_eq!(2f32.pow(&100.0).integer_decode(), (8388608u64, 77i16, 1i8)); + assert_eq!(2f32.powf(&100.0).integer_decode(), (8388608u64, 77i16, 1i8)); assert_eq!(0f32.integer_decode(), (0u64, -150i16, 1i8)); assert_eq!((-0f32).integer_decode(), (0u64, -150i16, -1i8)); assert_eq!(INFINITY.integer_decode(), (8388608u64, 105i16, 1i8)); diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs index fe51cb07646..7a06ef2e1af 100644 --- a/src/libstd/num/f64.rs +++ b/src/libstd/num/f64.rs @@ -411,7 +411,7 @@ fn ln_10() -> f64 { 2.30258509299404568401799145468436421 } fn recip(&self) -> f64 { 1.0 / *self } #[inline] - fn pow(&self, n: &f64) -> f64 { pow(*self, *n) } + fn powf(&self, n: &f64) -> f64 { pow(*self, *n) } #[inline] fn sqrt(&self) -> f64 { sqrt(*self) } @@ -1269,7 +1269,7 @@ fn test_frexp_nowin() { fn test_integer_decode() { assert_eq!(3.14159265359f64.integer_decode(), (7074237752028906u64, -51i16, 1i8)); assert_eq!((-8573.5918555f64).integer_decode(), (4713381968463931u64, -39i16, -1i8)); - assert_eq!(2f64.pow(&100.0).integer_decode(), (4503599627370496u64, 48i16, 1i8)); + assert_eq!(2f64.powf(&100.0).integer_decode(), (4503599627370496u64, 48i16, 1i8)); assert_eq!(0f64.integer_decode(), (0u64, -1075i16, 1i8)); assert_eq!((-0f64).integer_decode(), (0u64, -1075i16, -1i8)); assert_eq!(INFINITY.integer_decode(), (4503599627370496u64, 972i16, 1i8)); diff --git a/src/libstd/num/int.rs b/src/libstd/num/int.rs index 8068d4a74cb..dbc7c67d97b 100644 --- a/src/libstd/num/int.rs +++ b/src/libstd/num/int.rs @@ -121,38 +121,6 @@ fn checked_mul(&self, v: &int) -> Option { } } -/// Returns `base` raised to the power of `exponent` -pub fn pow(base: int, exponent: uint) -> int { - if exponent == 0u { - //Not mathemtically true if ~[base == 0] - return 1; - } - if base == 0 { return 0; } - let mut my_pow = exponent; - let mut acc = 1; - let mut multiplier = base; - while(my_pow > 0u) { - if my_pow % 2u == 1u { - acc *= multiplier; - } - my_pow /= 2u; - multiplier *= multiplier; - } - return acc; -} - -#[test] -fn test_pow() { - assert!((pow(0, 0u) == 1)); - assert!((pow(0, 1u) == 0)); - assert!((pow(0, 2u) == 0)); - assert!((pow(-1, 0u) == 1)); - assert!((pow(1, 0u) == 1)); - assert!((pow(-3, 2u) == 9)); - assert!((pow(-3, 3u) == -27)); - assert!((pow(4, 9u) == 262144)); -} - #[test] fn test_overflows() { assert!((::int::max_value > 0)); diff --git a/src/libstd/num/mod.rs b/src/libstd/num/mod.rs index 05f21c7d448..bcc95d6c48d 100644 --- a/src/libstd/num/mod.rs +++ b/src/libstd/num/mod.rs @@ -185,9 +185,9 @@ pub trait Real: Signed fn recip(&self) -> Self; // Algebraic functions - /// Raise a number to a power. - fn pow(&self, n: &Self) -> Self; + fn powf(&self, n: &Self) -> Self; + /// Take the square root of a number. fn sqrt(&self) -> Self; /// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`. @@ -263,6 +263,50 @@ pub trait Real: Signed fn to_radians(&self) -> Self; } +/// Raises a value to the power of exp, using +/// exponentiation by squaring. +/// +/// # Example +/// +/// ```rust +/// use std::num; +/// +/// let sixteen = num::pow(2, 4u); +/// assert_eq!(sixteen, 16); +/// ``` +#[inline] +pub fn pow>(num: T, exp: uint) -> T { + let one: uint = One::one(); + let num_one: T = One::one(); + + if exp.is_zero() { return num_one; } + if exp == one { return num.clone(); } + + let mut i: uint = exp; + let mut v: T; + let mut r: T = num_one; + + // This if is to avoid cloning self. + if (i & one) == one { + r = r * num; + i = i - one; + } + + i = i >> one; + v = num * num; + + while !i.is_zero() { + if (i & one) == one { + r = r * v; + i = i - one; + } + i = i >> one; + v = v * v; + } + + r +} + /// Raise a number to a power. /// /// # Example @@ -270,10 +314,10 @@ pub trait Real: Signed /// ```rust /// use std::num; /// -/// let sixteen: f64 = num::pow(2.0, 4.0); +/// let sixteen: f64 = num::powf(2.0, 4.0); /// assert_eq!(sixteen, 16.0); /// ``` -#[inline(always)] pub fn pow(value: T, n: T) -> T { value.pow(&n) } +#[inline(always)] pub fn powf(value: T, n: T) -> T { value.powf(&n) } /// Take the square root of a number. #[inline(always)] pub fn sqrt(value: T) -> T { value.sqrt() } /// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`. @@ -1074,6 +1118,7 @@ pub fn test_num(ten: T, two: T) { mod tests { use prelude::*; use super::*; + use num; use i8; use i16; use i32; @@ -1634,4 +1679,19 @@ fn test_from_primitive() { assert_eq!(from_f32(5f32), Some(Value { x: 5 })); assert_eq!(from_f64(5f64), Some(Value { x: 5 })); } + + #[test] + fn test_pow() { + fn assert_pow>(num: T, exp: uint) -> () { + assert_eq!(num::pow(num.clone(), exp), + range(1u, exp).fold(num.clone(), |acc, _| acc * num)); + } + + assert_eq!(num::pow(3, 0), 1); + assert_eq!(num::pow(5, 1), 5); + assert_pow(-4, 2); + assert_pow(8, 3); + assert_pow(8, 5); + assert_pow(2u64, 50); + } } diff --git a/src/libstd/rand/distributions/gamma.rs b/src/libstd/rand/distributions/gamma.rs index 38644f84707..2f1890b0233 100644 --- a/src/libstd/rand/distributions/gamma.rs +++ b/src/libstd/rand/distributions/gamma.rs @@ -144,7 +144,7 @@ impl IndependentSample for GammaSmallShape { fn ind_sample(&self, rng: &mut R) -> f64 { let Open01(u) = rng.gen::>(); - self.large_shape.ind_sample(rng) * num::pow(u, self.inv_shape) + self.large_shape.ind_sample(rng) * num::powf(u, self.inv_shape) } } impl IndependentSample for GammaLargeShape { diff --git a/src/libstd/sync/mpmc_bounded_queue.rs b/src/libstd/sync/mpmc_bounded_queue.rs index 18d17eed885..bf02bf204a5 100644 --- a/src/libstd/sync/mpmc_bounded_queue.rs +++ b/src/libstd/sync/mpmc_bounded_queue.rs @@ -31,10 +31,10 @@ use clone::Clone; use kinds::Send; -use num::{Real, Round}; use option::{Option, Some, None}; use sync::arc::UnsafeArc; use sync::atomics::{AtomicUint,Relaxed,Release,Acquire}; +use uint; use vec; struct Node { @@ -64,7 +64,7 @@ fn with_capacity(capacity: uint) -> State { 2u } else { // use next power of 2 as capacity - 2f64.pow(&((capacity as f64).log2().ceil())) as uint + uint::next_power_of_two(capacity) } } else { capacity diff --git a/src/test/bench/shootout-binarytrees.rs b/src/test/bench/shootout-binarytrees.rs index 976cd96ad30..7abbbdd278c 100644 --- a/src/test/bench/shootout-binarytrees.rs +++ b/src/test/bench/shootout-binarytrees.rs @@ -62,7 +62,7 @@ fn main() { let long_lived_tree = bottom_up_tree(&long_lived_arena, 0, max_depth); let mut messages = range_step(min_depth, max_depth + 1, 2).map(|depth| { - use std::int::pow; + use std::num::pow; let iterations = pow(2, (max_depth - depth + min_depth) as uint); do Future::spawn { let mut chk = 0;