From c9620dc0528866bda3a0d70036af082f45c78e96 Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Mon, 29 Apr 2013 15:33:55 +1000 Subject: [PATCH] Move appropriate functions out of Real and into separate Algebraic, Trigonometric, Exponential and Hyperbolic traits --- src/libcore/core.rc | 5 +- src/libcore/num/f32.rs | 148 +++++++++++++++--------------- src/libcore/num/f64.rs | 146 +++++++++++++++--------------- src/libcore/num/float.rs | 189 ++++++++++++++++++++++++--------------- src/libcore/num/num.rs | 73 +++++++-------- src/libcore/prelude.rs | 5 +- 6 files changed, 304 insertions(+), 262 deletions(-) diff --git a/src/libcore/core.rc b/src/libcore/core.rc index 158da9a12fc..bf92a30f7ce 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -104,8 +104,9 @@ pub use iter::{CopyableOrderedIter, CopyableNonstrictIter, Times}; pub use iter::{ExtendedMutableIter}; 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}; diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs index ada47fb597e..e687f482fa9 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -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::()) } @@ -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::() / 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 { diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs index 07a29652e94..d00e6ae2c0d 100644 --- a/src/libcore/num/f64.rs +++ b/src/libcore/num/f64.rs @@ -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::()) } @@ -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::() / 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 { diff --git a/src/libcore/num/float.rs b/src/libcore/num/float.rs index ef0adee884b..3aa8848cdbe 100644 --- a/src/libcore/num/float.rs +++ b/src/libcore/num/float.rs @@ -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::()) } + 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::() / 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 { diff --git a/src/libcore/num/num.rs b/src/libcore/num/num.rs index 0e2669a26b6..6fbc2985952 100644 --- a/src/libcore/num/num.rs +++ b/src/libcore/num/num.rs @@ -105,14 +105,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 +166,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; } /// diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs index 7e41f1b5b34..5fef01e65de 100644 --- a/src/libcore/prelude.rs +++ b/src/libcore/prelude.rs @@ -38,8 +38,9 @@ pub use iter::{BaseIter, ReverseIter, MutableIter, ExtendedIter, EqIter}; pub use iter::{CopyableIter, CopyableOrderedIter, CopyableNonstrictIter}; pub use iter::{Times, ExtendedMutableIter}; 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;