auto merge of : bjz/rust/numeric-traits, r=pcwalton

As discussed on issue , I have created four new traits: `Algebraic`, `Trigonometric`, `Exponential` and `Hyperbolic`, and moved the appropriate methods into them from `Real`.

~~~rust
pub trait Algebraic {
    fn pow(&self, n: Self) -> Self;
    fn sqrt(&self) -> Self;
    fn rsqrt(&self) -> Self;
    fn cbrt(&self) -> Self;
    fn hypot(&self, other: Self) -> Self;
}

pub trait Trigonometric {
    fn sin(&self) -> Self;
    fn cos(&self) -> Self;
    fn tan(&self) -> Self;
    fn asin(&self) -> Self;
    fn acos(&self) -> Self;
    fn atan(&self) -> Self;
    fn atan2(&self, other: Self) -> Self;
}

pub trait Exponential {
    fn exp(&self) -> Self;
    fn exp2(&self) -> Self;
    fn expm1(&self) -> Self;
    fn log(&self) -> Self;
    fn log2(&self) -> Self;
    fn log10(&self) -> Self;
}

pub trait Hyperbolic: Exponential {
    fn sinh(&self) -> Self;
    fn cosh(&self) -> Self;
    fn tanh(&self) -> Self;
}
~~~

There was some discussion over whether we should shorten the names, for example `Trig` and `Exp`. No abbreviations have been agreed on yet, but this could be considered in the future.

Additionally, `Integer::divisible_by` has been renamed to `Integer::is_multiple_of`.
This commit is contained in:
bors 2013-04-29 13:39:37 -07:00
commit dbcc3fe63a
10 changed files with 391 additions and 269 deletions

@ -105,8 +105,9 @@ pub use old_iter::{ExtendedMutableIter};
pub use iter::Times;
pub use num::{Num, NumCast};
pub use num::{Orderable, Signed, Unsigned, Integer};
pub use num::{Round, Fractional, Real, RealExt};
pub use num::{Orderable, Signed, Unsigned, Round};
pub use num::{Algebraic, Trigonometric, Exponential, Hyperbolic};
pub use num::{Integer, Fractional, Real, RealExt};
pub use num::{Bitwise, BitCount, Bounded};
pub use num::{Primitive, Int, Float};

@ -11,7 +11,6 @@
//! Operations and constants for `f32`
use from_str;
use libc::c_int;
use num::{Zero, One, strconv};
use prelude::*;
@ -102,8 +101,8 @@ delegate!(
fn sinh(n: c_float) -> c_float = c_float_utils::sinh,
fn tan(n: c_float) -> c_float = c_float_utils::tan,
fn tanh(n: c_float) -> c_float = c_float_utils::tanh,
fn tgamma(n: c_float) -> c_float = c_float_utils::tgamma)
fn tgamma(n: c_float) -> c_float = c_float_utils::tgamma
)
// These are not defined inside consts:: for consistency with
// the integer types
@ -368,6 +367,77 @@ impl Fractional for f32 {
fn recip(&self) -> f32 { 1.0 / *self }
}
impl Algebraic for f32 {
#[inline(always)]
fn pow(&self, n: f32) -> f32 { pow(*self, n) }
#[inline(always)]
fn sqrt(&self) -> f32 { sqrt(*self) }
#[inline(always)]
fn rsqrt(&self) -> f32 { self.sqrt().recip() }
#[inline(always)]
fn cbrt(&self) -> f32 { cbrt(*self) }
#[inline(always)]
fn hypot(&self, other: f32) -> f32 { hypot(*self, other) }
}
impl Trigonometric for f32 {
#[inline(always)]
fn sin(&self) -> f32 { sin(*self) }
#[inline(always)]
fn cos(&self) -> f32 { cos(*self) }
#[inline(always)]
fn tan(&self) -> f32 { tan(*self) }
#[inline(always)]
fn asin(&self) -> f32 { asin(*self) }
#[inline(always)]
fn acos(&self) -> f32 { acos(*self) }
#[inline(always)]
fn atan(&self) -> f32 { atan(*self) }
#[inline(always)]
fn atan2(&self, other: f32) -> f32 { atan2(*self, other) }
}
impl Exponential for f32 {
#[inline(always)]
fn exp(&self) -> f32 { exp(*self) }
#[inline(always)]
fn exp2(&self) -> f32 { exp2(*self) }
#[inline(always)]
fn expm1(&self) -> f32 { expm1(*self) }
#[inline(always)]
fn log(&self) -> f32 { ln(*self) }
#[inline(always)]
fn log2(&self) -> f32 { log2(*self) }
#[inline(always)]
fn log10(&self) -> f32 { log10(*self) }
}
impl Hyperbolic for f32 {
#[inline(always)]
fn sinh(&self) -> f32 { sinh(*self) }
#[inline(always)]
fn cosh(&self) -> f32 { cosh(*self) }
#[inline(always)]
fn tanh(&self) -> f32 { tanh(*self) }
}
impl Real for f32 {
/// Archimedes' constant
#[inline(always)]
@ -437,45 +507,6 @@ impl Real for f32 {
#[inline(always)]
fn log_10() -> f32 { 2.30258509299404568401799145468436421 }
#[inline(always)]
fn pow(&self, n: f32) -> f32 { pow(*self, n) }
#[inline(always)]
fn exp(&self) -> f32 { exp(*self) }
#[inline(always)]
fn exp2(&self) -> f32 { exp2(*self) }
#[inline(always)]
fn expm1(&self) -> f32 { expm1(*self) }
#[inline(always)]
fn ldexp(&self, n: int) -> f32 { ldexp(*self, n as c_int) }
#[inline(always)]
fn log(&self) -> f32 { ln(*self) }
#[inline(always)]
fn log2(&self) -> f32 { log2(*self) }
#[inline(always)]
fn log10(&self) -> f32 { log10(*self) }
#[inline(always)]
fn log_radix(&self) -> f32 { log_radix(*self) as f32 }
#[inline(always)]
fn ilog_radix(&self) -> int { ilog_radix(*self) as int }
#[inline(always)]
fn sqrt(&self) -> f32 { sqrt(*self) }
#[inline(always)]
fn rsqrt(&self) -> f32 { self.sqrt().recip() }
#[inline(always)]
fn cbrt(&self) -> f32 { cbrt(*self) }
/// Converts to degrees, assuming the number is in radians
#[inline(always)]
fn to_degrees(&self) -> f32 { *self * (180.0 / Real::pi::<f32>()) }
@ -483,39 +514,6 @@ impl Real for f32 {
/// Converts to radians, assuming the number is in degrees
#[inline(always)]
fn to_radians(&self) -> f32 { *self * (Real::pi::<f32>() / 180.0) }
#[inline(always)]
fn hypot(&self, other: f32) -> f32 { hypot(*self, other) }
#[inline(always)]
fn sin(&self) -> f32 { sin(*self) }
#[inline(always)]
fn cos(&self) -> f32 { cos(*self) }
#[inline(always)]
fn tan(&self) -> f32 { tan(*self) }
#[inline(always)]
fn asin(&self) -> f32 { asin(*self) }
#[inline(always)]
fn acos(&self) -> f32 { acos(*self) }
#[inline(always)]
fn atan(&self) -> f32 { atan(*self) }
#[inline(always)]
fn atan2(&self, other: f32) -> f32 { atan2(*self, other) }
#[inline(always)]
fn sinh(&self) -> f32 { sinh(*self) }
#[inline(always)]
fn cosh(&self) -> f32 { cosh(*self) }
#[inline(always)]
fn tanh(&self) -> f32 { tanh(*self) }
}
impl Bounded for f32 {

@ -109,7 +109,8 @@ delegate!(
fn jn(i: c_int, n: c_double) -> c_double = c_double_utils::jn,
fn y0(n: c_double) -> c_double = c_double_utils::y0,
fn y1(n: c_double) -> c_double = c_double_utils::y1,
fn yn(i: c_int, n: c_double) -> c_double = c_double_utils::yn)
fn yn(i: c_int, n: c_double) -> c_double = c_double_utils::yn
)
// FIXME (#1433): obtain these in a different way
@ -378,6 +379,77 @@ impl Fractional for f64 {
fn recip(&self) -> f64 { 1.0 / *self }
}
impl Algebraic for f64 {
#[inline(always)]
fn pow(&self, n: f64) -> f64 { pow(*self, n) }
#[inline(always)]
fn sqrt(&self) -> f64 { sqrt(*self) }
#[inline(always)]
fn rsqrt(&self) -> f64 { self.sqrt().recip() }
#[inline(always)]
fn cbrt(&self) -> f64 { cbrt(*self) }
#[inline(always)]
fn hypot(&self, other: f64) -> f64 { hypot(*self, other) }
}
impl Trigonometric for f64 {
#[inline(always)]
fn sin(&self) -> f64 { sin(*self) }
#[inline(always)]
fn cos(&self) -> f64 { cos(*self) }
#[inline(always)]
fn tan(&self) -> f64 { tan(*self) }
#[inline(always)]
fn asin(&self) -> f64 { asin(*self) }
#[inline(always)]
fn acos(&self) -> f64 { acos(*self) }
#[inline(always)]
fn atan(&self) -> f64 { atan(*self) }
#[inline(always)]
fn atan2(&self, other: f64) -> f64 { atan2(*self, other) }
}
impl Exponential for f64 {
#[inline(always)]
fn exp(&self) -> f64 { exp(*self) }
#[inline(always)]
fn exp2(&self) -> f64 { exp2(*self) }
#[inline(always)]
fn expm1(&self) -> f64 { expm1(*self) }
#[inline(always)]
fn log(&self) -> f64 { ln(*self) }
#[inline(always)]
fn log2(&self) -> f64 { log2(*self) }
#[inline(always)]
fn log10(&self) -> f64 { log10(*self) }
}
impl Hyperbolic for f64 {
#[inline(always)]
fn sinh(&self) -> f64 { sinh(*self) }
#[inline(always)]
fn cosh(&self) -> f64 { cosh(*self) }
#[inline(always)]
fn tanh(&self) -> f64 { tanh(*self) }
}
impl Real for f64 {
/// Archimedes' constant
#[inline(always)]
@ -447,45 +519,6 @@ impl Real for f64 {
#[inline(always)]
fn log_10() -> f64 { 2.30258509299404568401799145468436421 }
#[inline(always)]
fn pow(&self, n: f64) -> f64 { pow(*self, n) }
#[inline(always)]
fn exp(&self) -> f64 { exp(*self) }
#[inline(always)]
fn exp2(&self) -> f64 { exp2(*self) }
#[inline(always)]
fn expm1(&self) -> f64 { expm1(*self) }
#[inline(always)]
fn ldexp(&self, n: int) -> f64 { ldexp(*self, n as c_int) }
#[inline(always)]
fn log(&self) -> f64 { ln(*self) }
#[inline(always)]
fn log2(&self) -> f64 { log2(*self) }
#[inline(always)]
fn log10(&self) -> f64 { log10(*self) }
#[inline(always)]
fn log_radix(&self) -> f64 { log_radix(*self) }
#[inline(always)]
fn ilog_radix(&self) -> int { ilog_radix(*self) as int }
#[inline(always)]
fn sqrt(&self) -> f64 { sqrt(*self) }
#[inline(always)]
fn rsqrt(&self) -> f64 { self.sqrt().recip() }
#[inline(always)]
fn cbrt(&self) -> f64 { cbrt(*self) }
/// Converts to degrees, assuming the number is in radians
#[inline(always)]
fn to_degrees(&self) -> f64 { *self * (180.0 / Real::pi::<f64>()) }
@ -493,39 +526,6 @@ impl Real for f64 {
/// Converts to radians, assuming the number is in degrees
#[inline(always)]
fn to_radians(&self) -> f64 { *self * (Real::pi::<f64>() / 180.0) }
#[inline(always)]
fn hypot(&self, other: f64) -> f64 { hypot(*self, other) }
#[inline(always)]
fn sin(&self) -> f64 { sin(*self) }
#[inline(always)]
fn cos(&self) -> f64 { cos(*self) }
#[inline(always)]
fn tan(&self) -> f64 { tan(*self) }
#[inline(always)]
fn asin(&self) -> f64 { asin(*self) }
#[inline(always)]
fn acos(&self) -> f64 { acos(*self) }
#[inline(always)]
fn atan(&self) -> f64 { atan(*self) }
#[inline(always)]
fn atan2(&self, other: f64) -> f64 { atan2(*self, other) }
#[inline(always)]
fn sinh(&self) -> f64 { sinh(*self) }
#[inline(always)]
fn cosh(&self) -> f64 { cosh(*self) }
#[inline(always)]
fn tanh(&self) -> f64 { tanh(*self) }
}
impl RealExt for f64 {

@ -453,6 +453,119 @@ impl Fractional for float {
fn recip(&self) -> float { 1.0 / *self }
}
impl Algebraic for float {
#[inline(always)]
fn pow(&self, n: float) -> float {
(*self as f64).pow(n as f64) as float
}
#[inline(always)]
fn sqrt(&self) -> float {
(*self as f64).sqrt() as float
}
#[inline(always)]
fn rsqrt(&self) -> float {
(*self as f64).rsqrt() as float
}
#[inline(always)]
fn cbrt(&self) -> float {
(*self as f64).cbrt() as float
}
#[inline(always)]
fn hypot(&self, other: float) -> float {
(*self as f64).hypot(other as f64) as float
}
}
impl Trigonometric for float {
#[inline(always)]
fn sin(&self) -> float {
(*self as f64).sin() as float
}
#[inline(always)]
fn cos(&self) -> float {
(*self as f64).cos() as float
}
#[inline(always)]
fn tan(&self) -> float {
(*self as f64).tan() as float
}
#[inline(always)]
fn asin(&self) -> float {
(*self as f64).asin() as float
}
#[inline(always)]
fn acos(&self) -> float {
(*self as f64).acos() as float
}
#[inline(always)]
fn atan(&self) -> float {
(*self as f64).atan() as float
}
#[inline(always)]
fn atan2(&self, other: float) -> float {
(*self as f64).atan2(other as f64) as float
}
}
impl Exponential for float {
#[inline(always)]
fn exp(&self) -> float {
(*self as f64).exp() as float
}
#[inline(always)]
fn exp2(&self) -> float {
(*self as f64).exp2() as float
}
#[inline(always)]
fn expm1(&self) -> float {
(*self as f64).expm1() as float
}
#[inline(always)]
fn log(&self) -> float {
(*self as f64).log() as float
}
#[inline(always)]
fn log2(&self) -> float {
(*self as f64).log2() as float
}
#[inline(always)]
fn log10(&self) -> float {
(*self as f64).log10() as float
}
}
impl Hyperbolic for float {
#[inline(always)]
fn sinh(&self) -> float {
(*self as f64).sinh() as float
}
#[inline(always)]
fn cosh(&self) -> float {
(*self as f64).cosh() as float
}
#[inline(always)]
fn tanh(&self) -> float {
(*self as f64).tanh() as float
}
}
impl Real for float {
/// Archimedes' constant
#[inline(always)]
@ -522,85 +635,13 @@ impl Real for float {
#[inline(always)]
fn log_10() -> float { 2.30258509299404568401799145468436421 }
#[inline(always)]
fn pow(&self, n: float) -> float { pow(*self as f64, n as f64) as float }
#[inline(always)]
fn exp(&self) -> float { exp(*self as f64) as float }
#[inline(always)]
fn exp2(&self) -> float { exp2(*self as f64) as float }
#[inline(always)]
fn expm1(&self) -> float { expm1(*self as f64) as float }
#[inline(always)]
fn ldexp(&self, n: int) -> float { ldexp(*self as f64, n as c_int) as float }
#[inline(always)]
fn log(&self) -> float { ln(*self as f64) as float }
#[inline(always)]
fn log2(&self) -> float { log2(*self as f64) as float }
#[inline(always)]
fn log10(&self) -> float { log10(*self as f64) as float }
#[inline(always)]
fn log_radix(&self) -> float { log_radix(*self as f64) as float }
#[inline(always)]
fn ilog_radix(&self) -> int { ilog_radix(*self as f64) as int }
#[inline(always)]
fn sqrt(&self) -> float { sqrt(*self) }
#[inline(always)]
fn rsqrt(&self) -> float { self.sqrt().recip() }
#[inline(always)]
fn cbrt(&self) -> float { cbrt(*self as f64) as float }
/// Converts to degrees, assuming the number is in radians
#[inline(always)]
fn to_degrees(&self) -> float { *self * (180.0 / Real::pi::<float>()) }
fn to_degrees(&self) -> float { (*self as f64).to_degrees() as float }
/// Converts to radians, assuming the number is in degrees
#[inline(always)]
fn to_radians(&self) -> float { *self * (Real::pi::<float>() / 180.0) }
#[inline(always)]
fn hypot(&self, other: float) -> float { hypot(*self as f64, other as f64) as float }
#[inline(always)]
fn sin(&self) -> float { sin(*self) }
#[inline(always)]
fn cos(&self) -> float { cos(*self) }
#[inline(always)]
fn tan(&self) -> float { tan(*self) }
#[inline(always)]
fn asin(&self) -> float { asin(*self as f64) as float }
#[inline(always)]
fn acos(&self) -> float { acos(*self as f64) as float }
#[inline(always)]
fn atan(&self) -> float { atan(*self) }
#[inline(always)]
fn atan2(&self, other: float) -> float { atan2(*self as f64, other as f64) as float }
#[inline(always)]
fn sinh(&self) -> float { sinh(*self as f64) as float }
#[inline(always)]
fn cosh(&self) -> float { cosh(*self as f64) as float }
#[inline(always)]
fn tanh(&self) -> float { tanh(*self as f64) as float }
fn to_radians(&self) -> float { (*self as f64).to_radians() as float }
}
impl RealExt for float {

@ -406,11 +406,11 @@ impl Integer for T {
/// Returns `true` if the number can be divided by `other` without leaving a remainder
#[inline(always)]
fn divisible_by(&self, other: &T) -> bool { *self % *other == 0 }
fn is_multiple_of(&self, other: &T) -> bool { *self % *other == 0 }
/// Returns `true` if the number is divisible by `2`
#[inline(always)]
fn is_even(&self) -> bool { self.divisible_by(&2) }
fn is_even(&self) -> bool { self.is_multiple_of(&2) }
/// Returns `true` if the number is not divisible by `2`
#[inline(always)]
@ -682,6 +682,42 @@ mod tests {
assert_eq!(-(0b11 as T) - (1 as T), (0b11 as T).not());
}
#[test]
fn test_multiple_of() {
assert!((6 as T).is_multiple_of(&(6 as T)));
assert!((6 as T).is_multiple_of(&(3 as T)));
assert!((6 as T).is_multiple_of(&(1 as T)));
assert!((-8 as T).is_multiple_of(&(4 as T)));
assert!((8 as T).is_multiple_of(&(-1 as T)));
assert!((-8 as T).is_multiple_of(&(-2 as T)));
}
#[test]
fn test_even() {
assert_eq!((-4 as T).is_even(), true);
assert_eq!((-3 as T).is_even(), false);
assert_eq!((-2 as T).is_even(), true);
assert_eq!((-1 as T).is_even(), false);
assert_eq!((0 as T).is_even(), true);
assert_eq!((1 as T).is_even(), false);
assert_eq!((2 as T).is_even(), true);
assert_eq!((3 as T).is_even(), false);
assert_eq!((4 as T).is_even(), true);
}
#[test]
fn test_odd() {
assert_eq!((-4 as T).is_odd(), false);
assert_eq!((-3 as T).is_odd(), true);
assert_eq!((-2 as T).is_odd(), false);
assert_eq!((-1 as T).is_odd(), true);
assert_eq!((0 as T).is_odd(), false);
assert_eq!((1 as T).is_odd(), true);
assert_eq!((2 as T).is_odd(), false);
assert_eq!((3 as T).is_odd(), true);
assert_eq!((4 as T).is_odd(), false);
}
#[test]
fn test_bitcount() {
assert_eq!((0b010101 as T).population_count(), 3);

@ -85,7 +85,8 @@ pub trait Integer: Num
fn gcd(&self, other: &Self) -> Self;
fn lcm(&self, other: &Self) -> Self;
fn divisible_by(&self, other: &Self) -> bool;
fn is_multiple_of(&self, other: &Self) -> bool;
fn is_even(&self) -> bool;
fn is_odd(&self) -> bool;
}
@ -105,14 +106,47 @@ pub trait Fractional: Num
fn recip(&self) -> Self;
}
pub trait Algebraic {
fn pow(&self, n: Self) -> Self;
fn sqrt(&self) -> Self;
fn rsqrt(&self) -> Self;
fn cbrt(&self) -> Self;
fn hypot(&self, other: Self) -> Self;
}
pub trait Trigonometric {
fn sin(&self) -> Self;
fn cos(&self) -> Self;
fn tan(&self) -> Self;
fn asin(&self) -> Self;
fn acos(&self) -> Self;
fn atan(&self) -> Self;
fn atan2(&self, other: Self) -> Self;
}
pub trait Exponential {
fn exp(&self) -> Self;
fn exp2(&self) -> Self;
fn expm1(&self) -> Self;
fn log(&self) -> Self;
fn log2(&self) -> Self;
fn log10(&self) -> Self;
}
pub trait Hyperbolic: Exponential {
fn sinh(&self) -> Self;
fn cosh(&self) -> Self;
fn tanh(&self) -> Self;
}
///
/// Defines constants and methods common to real numbers
///
pub trait Real: Signed
+ Fractional {
// FIXME (#5527): usages of `int` should be replaced with an associated
// integer type once these are implemented
+ Fractional
+ Algebraic
+ Trigonometric
+ Hyperbolic {
// Common Constants
// FIXME (#5527): These should be associated constants
fn pi() -> Self;
@ -133,41 +167,9 @@ pub trait Real: Signed
fn log_2() -> Self;
fn log_10() -> Self;
// Exponential functions
fn pow(&self, n: Self) -> Self;
fn exp(&self) -> Self;
fn exp2(&self) -> Self;
fn expm1(&self) -> Self;
fn ldexp(&self, n: int) -> Self;
fn log(&self) -> Self;
fn log2(&self) -> Self;
fn log10(&self) -> Self;
fn log_radix(&self) -> Self;
fn ilog_radix(&self) -> int;
fn sqrt(&self) -> Self;
fn rsqrt(&self) -> Self;
fn cbrt(&self) -> Self;
// Angular conversions
fn to_degrees(&self) -> Self;
fn to_radians(&self) -> Self;
// Triganomic functions
fn hypot(&self, other: Self) -> Self;
fn sin(&self) -> Self;
fn cos(&self) -> Self;
fn tan(&self) -> Self;
// Inverse triganomic functions
fn asin(&self) -> Self;
fn acos(&self) -> Self;
fn atan(&self) -> Self;
fn atan2(&self, other: Self) -> Self;
// Hyperbolic triganomic functions
fn sinh(&self) -> Self;
fn cosh(&self) -> Self;
fn tanh(&self) -> Self;
}
///

@ -238,11 +238,11 @@ impl Integer for T {
/// Returns `true` if the number can be divided by `other` without leaving a remainder
#[inline(always)]
fn divisible_by(&self, other: &T) -> bool { *self % *other == 0 }
fn is_multiple_of(&self, other: &T) -> bool { *self % *other == 0 }
/// Returns `true` if the number is divisible by `2`
#[inline(always)]
fn is_even(&self) -> bool { self.divisible_by(&2) }
fn is_even(&self) -> bool { self.is_multiple_of(&2) }
/// Returns `true` if the number is not divisible by `2`
#[inline(always)]
@ -415,6 +415,31 @@ mod tests {
assert_eq!((99 as T).lcm(&17), 1683 as T);
}
#[test]
fn test_multiple_of() {
assert!((6 as T).is_multiple_of(&(6 as T)));
assert!((6 as T).is_multiple_of(&(3 as T)));
assert!((6 as T).is_multiple_of(&(1 as T)));
}
#[test]
fn test_even() {
assert_eq!((0 as T).is_even(), true);
assert_eq!((1 as T).is_even(), false);
assert_eq!((2 as T).is_even(), true);
assert_eq!((3 as T).is_even(), false);
assert_eq!((4 as T).is_even(), true);
}
#[test]
fn test_odd() {
assert_eq!((0 as T).is_odd(), false);
assert_eq!((1 as T).is_odd(), true);
assert_eq!((2 as T).is_odd(), false);
assert_eq!((3 as T).is_odd(), true);
assert_eq!((4 as T).is_odd(), false);
}
#[test]
fn test_bitwise() {
assert_eq!(0b1110 as T, (0b1100 as T).bitor(&(0b1010 as T)));

@ -39,8 +39,9 @@ pub use old_iter::{CopyableIter, CopyableOrderedIter, CopyableNonstrictIter};
pub use old_iter::{ExtendedMutableIter};
pub use iter::Times;
pub use num::{Num, NumCast};
pub use num::{Orderable, Signed, Unsigned, Integer};
pub use num::{Round, Fractional, Real, RealExt};
pub use num::{Orderable, Signed, Unsigned, Round};
pub use num::{Algebraic, Trigonometric, Exponential, Hyperbolic};
pub use num::{Integer, Fractional, Real, RealExt};
pub use num::{Bitwise, BitCount, Bounded};
pub use num::{Primitive, Int, Float};
pub use path::GenericPath;

@ -428,7 +428,7 @@ impl Integer for BigUint {
/// Returns `true` if the number can be divided by `other` without leaving a remainder
#[inline(always)]
fn divisible_by(&self, other: &BigUint) -> bool { (*self % *other).is_zero() }
fn is_multiple_of(&self, other: &BigUint) -> bool { (*self % *other).is_zero() }
/// Returns `true` if the number is divisible by `2`
#[inline(always)]
@ -973,7 +973,7 @@ impl Integer for BigInt {
/// Returns `true` if the number can be divided by `other` without leaving a remainder
#[inline(always)]
fn divisible_by(&self, other: &BigInt) -> bool { self.data.divisible_by(&other.data) }
fn is_multiple_of(&self, other: &BigInt) -> bool { self.data.is_multiple_of(&other.data) }
/// Returns `true` if the number is divisible by `2`
#[inline(always)]

@ -203,6 +203,9 @@ impl<T: Copy + Num + Ord>
}
}
impl<T: Copy + Num + Ord>
Num for Ratio<T> {}
/* Utils */
impl<T: Copy + Num + Ord>
Round for Ratio<T> {
@ -242,6 +245,12 @@ impl<T: Copy + Num + Ord>
}
}
impl<T: Copy + Num + Ord> Fractional for Ratio<T> {
#[inline]
fn recip(&self) -> Ratio<T> {
Ratio::new_raw(self.denom, self.numer)
}
}
/* String conversions */
impl<T: ToStr> ToStr for Ratio<T> {
@ -446,6 +455,15 @@ mod test {
assert_eq!(_3_2.fract(), _1_2);
}
#[test]
fn test_recip() {
assert_eq!(_1 * _1.recip(), _1);
assert_eq!(_2 * _2.recip(), _1);
assert_eq!(_1_2 * _1_2.recip(), _1);
assert_eq!(_3_2 * _3_2.recip(), _1);
assert_eq!(_neg1_2 * _neg1_2.recip(), _1);
}
#[test]
fn test_to_from_str() {
fn test(r: Rational, s: ~str) {