Skip to content
Permalink
Browse files

libcore/num: implement pow() as a trait method of Pow.

  • Loading branch information...
nodakai committed Sep 29, 2014
1 parent 1f3cda8 commit f125678e09ac69c9f203d13445b08df7a8843c3a
Showing with 27 additions and 12 deletions.
  1. +21 −5 src/libcore/num/mod.rs
  2. +2 −2 src/libserialize/json.rs
  3. +1 −1 src/libstd/num/mod.rs
  4. +3 −4 src/libstd/num/strconv.rs
@@ -25,6 +25,8 @@ use mem::size_of;
use ops::{Add, Sub, Mul, Div, Rem, Neg}; use ops::{Add, Sub, Mul, Div, Rem, Neg};
use ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr}; use ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr};
use option::{Option, Some, None}; use option::{Option, Some, None};
use num;
use clone;


/// The base trait for numeric types /// The base trait for numeric types
pub trait Num: PartialEq + Zero + One pub trait Num: PartialEq + Zero + One
@@ -319,11 +321,19 @@ trait_impl!(Unsigned for uint u8 u16 u32 u64)
/// ///
/// assert_eq!(num::pow(2i, 4), 16); /// assert_eq!(num::pow(2i, 4), 16);
/// ``` /// ```
#[inline] pub trait Pow {
pub fn pow<T: One + Mul<T, T>>(mut base: T, mut exp: uint) -> T { /// Calcurate self * self * ... * self (exp times).
if exp == 1 { base } fn pow(&self, mut exp: uint) -> Self;
else {
let mut acc = one::<T>(); /// Calcurate self * self.
fn sq(&self) -> Self;
}

impl<M: num::One + Mul<M, M> + clone::Clone> Pow for M {
#[inline]
fn pow(&self, mut exp: uint) -> M {
let mut base = self.clone();
let mut acc = num::one::<M>();
while exp > 0 { while exp > 0 {
if (exp & 1) == 1 { if (exp & 1) == 1 {
acc = acc * base; acc = acc * base;
@@ -333,6 +343,12 @@ pub fn pow<T: One + Mul<T, T>>(mut base: T, mut exp: uint) -> T {
} }
acc acc
} }

#[inline]
fn sq(&self) -> M {
let s = self.clone();
s * s
}
} }


/// Numbers which have upper and lower bounds /// Numbers which have upper and lower bounds
@@ -199,7 +199,7 @@ use std::collections::{HashMap, TreeMap};
use std::{char, f64, fmt, io, num, str}; use std::{char, f64, fmt, io, num, str};
use std::io::MemWriter; use std::io::MemWriter;
use std::mem::{swap, transmute}; use std::mem::{swap, transmute};
use std::num::{FPNaN, FPInfinite}; use std::num::{FPNaN, FPInfinite, Pow};
use std::str::ScalarValue; use std::str::ScalarValue;
use std::string; use std::string;
use std::vec::Vec; use std::vec::Vec;
@@ -1472,7 +1472,7 @@ impl<T: Iterator<char>> Parser<T> {
} }
} }


let exp = num::pow(10_f64, exp); let exp = 10_f64.pow(exp);
if neg_exp { if neg_exp {
res /= exp; res /= exp;
} else { } else {
@@ -23,7 +23,7 @@ use string::String;


pub use core::num::{Num, div_rem, Zero, zero, One, one}; pub use core::num::{Num, div_rem, Zero, zero, One, one};
pub use core::num::{Signed, abs, abs_sub, signum}; pub use core::num::{Signed, abs, abs_sub, signum};
pub use core::num::{Unsigned, pow, Bounded}; pub use core::num::{Unsigned, Pow, Bounded};
pub use core::num::{Primitive, Int, Saturating}; pub use core::num::{Primitive, Int, Saturating};
pub use core::num::{CheckedAdd, CheckedSub, CheckedMul, CheckedDiv}; pub use core::num::{CheckedAdd, CheckedSub, CheckedMul, CheckedDiv};
pub use core::num::{cast, FromPrimitive, NumCast, ToPrimitive}; pub use core::num::{cast, FromPrimitive, NumCast, ToPrimitive};
@@ -15,9 +15,8 @@
use char; use char;
use clone::Clone; use clone::Clone;
use collections::{Collection, MutableSeq}; use collections::{Collection, MutableSeq};
use num::{NumCast, Zero, One, cast, Int}; use num::{NumCast, Zero, One, Pow, cast, Int};
use num::{Float, FPNaN, FPInfinite, ToPrimitive}; use num::{Float, FPNaN, FPInfinite, ToPrimitive};
use num;
use ops::{Add, Sub, Mul, Div, Rem, Neg}; use ops::{Add, Sub, Mul, Div, Rem, Neg};
use option::{None, Option, Some}; use option::{None, Option, Some};
use slice::{ImmutableSlice, MutableSlice}; use slice::{ImmutableSlice, MutableSlice};
@@ -736,9 +735,9 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+PartialEq+PartialOrd+Div<T,T>+
match exp { match exp {
Some(exp_pow) => { Some(exp_pow) => {
multiplier = if exp_pow < 0 { multiplier = if exp_pow < 0 {
_1 / num::pow(base, (-exp_pow.to_int().unwrap()) as uint) _1 / base.pow((-exp_pow.to_int().unwrap()) as uint)
} else { } else {
num::pow(base, exp_pow.to_int().unwrap() as uint) base.pow(exp_pow.to_int().unwrap() as uint)
} }
} }
None => return None // invalid exponent -> invalid number None => return None // invalid exponent -> invalid number

0 comments on commit f125678

Please sign in to comment.
You can’t perform that action at this time.