From c9620dc0528866bda3a0d70036af082f45c78e96 Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Mon, 29 Apr 2013 15:33:55 +1000 Subject: Move appropriate functions out of Real and into separate Algebraic, Trigonometric, Exponential and Hyperbolic traits --- src/libcore/num/float.rs | 179 +++++++++++++++++++++++++++++------------------ 1 file changed, 110 insertions(+), 69 deletions(-) (limited to 'src/libcore/num/float.rs') 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,154 +453,195 @@ impl Fractional for float { fn recip(&self) -> float { 1.0 / *self } } -impl Real for float { - /// Archimedes' constant - #[inline(always)] - fn pi() -> float { 3.14159265358979323846264338327950288 } - - /// 2.0 * pi - #[inline(always)] - fn two_pi() -> float { 6.28318530717958647692528676655900576 } - - /// pi / 2.0 - #[inline(always)] - fn frac_pi_2() -> float { 1.57079632679489661923132169163975144 } - - /// pi / 3.0 +impl Algebraic for float { #[inline(always)] - fn frac_pi_3() -> float { 1.04719755119659774615421446109316763 } + fn pow(&self, n: float) -> float { + (*self as f64).pow(n as f64) as float + } - /// pi / 4.0 #[inline(always)] - fn frac_pi_4() -> float { 0.785398163397448309615660845819875721 } + fn sqrt(&self) -> float { + (*self as f64).sqrt() as float + } - /// pi / 6.0 #[inline(always)] - fn frac_pi_6() -> float { 0.52359877559829887307710723054658381 } + fn rsqrt(&self) -> float { + (*self as f64).rsqrt() as float + } - /// pi / 8.0 #[inline(always)] - fn frac_pi_8() -> float { 0.39269908169872415480783042290993786 } + fn cbrt(&self) -> float { + (*self as f64).cbrt() as float + } - /// 1.0 / pi #[inline(always)] - fn frac_1_pi() -> float { 0.318309886183790671537767526745028724 } + fn hypot(&self, other: float) -> float { + (*self as f64).hypot(other as f64) as float + } +} - /// 2.0 / pi +impl Trigonometric for float { #[inline(always)] - fn frac_2_pi() -> float { 0.636619772367581343075535053490057448 } + fn sin(&self) -> float { + (*self as f64).sin() as float + } - /// 2 .0/ sqrt(pi) #[inline(always)] - fn frac_2_sqrtpi() -> float { 1.12837916709551257389615890312154517 } + fn cos(&self) -> float { + (*self as f64).cos() as float + } - /// sqrt(2.0) #[inline(always)] - fn sqrt2() -> float { 1.41421356237309504880168872420969808 } + fn tan(&self) -> float { + (*self as f64).tan() as float + } - /// 1.0 / sqrt(2.0) #[inline(always)] - fn frac_1_sqrt2() -> float { 0.707106781186547524400844362104849039 } + fn asin(&self) -> float { + (*self as f64).asin() as float + } - /// Euler's number #[inline(always)] - fn e() -> float { 2.71828182845904523536028747135266250 } + fn acos(&self) -> float { + (*self as f64).acos() as float + } - /// log2(e) #[inline(always)] - fn log2_e() -> float { 1.44269504088896340735992468100189214 } + fn atan(&self) -> float { + (*self as f64).atan() as float + } - /// log10(e) #[inline(always)] - fn log10_e() -> float { 0.434294481903251827651128918916605082 } + fn atan2(&self, other: float) -> float { + (*self as f64).atan2(other as f64) as float + } +} - /// log(2.0) +impl Exponential for float { #[inline(always)] - fn log_2() -> float { 0.693147180559945309417232121458176568 } + fn exp(&self) -> float { + (*self as f64).exp() as float + } - /// log(10.0) #[inline(always)] - fn log_10() -> float { 2.30258509299404568401799145468436421 } + fn exp2(&self) -> float { + (*self as f64).exp2() as float + } #[inline(always)] - fn pow(&self, n: float) -> float { pow(*self as f64, n as f64) as float } + fn expm1(&self) -> float { + (*self as f64).expm1() as float + } #[inline(always)] - fn exp(&self) -> float { exp(*self as f64) as float } + fn log(&self) -> float { + (*self as f64).log() as float + } #[inline(always)] - fn exp2(&self) -> float { exp2(*self as f64) as float } + fn log2(&self) -> float { + (*self as f64).log2() as float + } #[inline(always)] - fn expm1(&self) -> float { expm1(*self as f64) as float } + fn log10(&self) -> float { + (*self as f64).log10() as float + } +} +impl Hyperbolic for float { #[inline(always)] - fn ldexp(&self, n: int) -> float { ldexp(*self as f64, n as c_int) as float } + fn sinh(&self) -> float { + (*self as f64).sinh() as float + } #[inline(always)] - fn log(&self) -> float { ln(*self as f64) as float } + fn cosh(&self) -> float { + (*self as f64).cosh() as float + } #[inline(always)] - fn log2(&self) -> float { log2(*self as f64) as float } + fn tanh(&self) -> float { + (*self as f64).tanh() as float + } +} +impl Real for float { + /// Archimedes' constant #[inline(always)] - fn log10(&self) -> float { log10(*self as f64) as float } + fn pi() -> float { 3.14159265358979323846264338327950288 } + /// 2.0 * pi #[inline(always)] - fn log_radix(&self) -> float { log_radix(*self as f64) as float } + fn two_pi() -> float { 6.28318530717958647692528676655900576 } + /// pi / 2.0 #[inline(always)] - fn ilog_radix(&self) -> int { ilog_radix(*self as f64) as int } + fn frac_pi_2() -> float { 1.57079632679489661923132169163975144 } + /// pi / 3.0 #[inline(always)] - fn sqrt(&self) -> float { sqrt(*self) } + fn frac_pi_3() -> float { 1.04719755119659774615421446109316763 } + /// pi / 4.0 #[inline(always)] - fn rsqrt(&self) -> float { self.sqrt().recip() } + fn frac_pi_4() -> float { 0.785398163397448309615660845819875721 } + /// pi / 6.0 #[inline(always)] - fn cbrt(&self) -> float { cbrt(*self as f64) as float } + fn frac_pi_6() -> float { 0.52359877559829887307710723054658381 } - /// Converts to degrees, assuming the number is in radians + /// pi / 8.0 #[inline(always)] - fn to_degrees(&self) -> float { *self * (180.0 / Real::pi::()) } + fn frac_pi_8() -> float { 0.39269908169872415480783042290993786 } - /// Converts to radians, assuming the number is in degrees + /// 1.0 / pi #[inline(always)] - fn to_radians(&self) -> float { *self * (Real::pi::() / 180.0) } + fn frac_1_pi() -> float { 0.318309886183790671537767526745028724 } + /// 2.0 / pi #[inline(always)] - fn hypot(&self, other: float) -> float { hypot(*self as f64, other as f64) as float } + fn frac_2_pi() -> float { 0.636619772367581343075535053490057448 } + /// 2 .0/ sqrt(pi) #[inline(always)] - fn sin(&self) -> float { sin(*self) } + fn frac_2_sqrtpi() -> float { 1.12837916709551257389615890312154517 } + /// sqrt(2.0) #[inline(always)] - fn cos(&self) -> float { cos(*self) } + fn sqrt2() -> float { 1.41421356237309504880168872420969808 } + /// 1.0 / sqrt(2.0) #[inline(always)] - fn tan(&self) -> float { tan(*self) } + fn frac_1_sqrt2() -> float { 0.707106781186547524400844362104849039 } + /// Euler's number #[inline(always)] - fn asin(&self) -> float { asin(*self as f64) as float } + fn e() -> float { 2.71828182845904523536028747135266250 } + /// log2(e) #[inline(always)] - fn acos(&self) -> float { acos(*self as f64) as float } + fn log2_e() -> float { 1.44269504088896340735992468100189214 } + /// log10(e) #[inline(always)] - fn atan(&self) -> float { atan(*self) } + fn log10_e() -> float { 0.434294481903251827651128918916605082 } + /// log(2.0) #[inline(always)] - fn atan2(&self, other: float) -> float { atan2(*self as f64, other as f64) as float } + fn log_2() -> float { 0.693147180559945309417232121458176568 } + /// log(10.0) #[inline(always)] - fn sinh(&self) -> float { sinh(*self as f64) as float } + fn log_10() -> float { 2.30258509299404568401799145468436421 } + /// Converts to degrees, assuming the number is in radians #[inline(always)] - fn cosh(&self) -> float { cosh(*self as f64) as 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 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 { -- cgit 1.4.1-3-g733a5 From d3f494f5c3ce96da2e0c8090fc17a8738e4396c1 Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Mon, 29 Apr 2013 22:15:58 +1000 Subject: Merge Exponential and Hyperbolic traits The Hyperbolic Functions are trivially implemented in terms of `exp`, so it's simpler to group them the Exponential trait. In the future these would have default implementations. --- src/libcore/core.rc | 2 +- src/libcore/num/f32.rs | 2 -- src/libcore/num/f64.rs | 2 -- src/libcore/num/float.rs | 2 -- src/libcore/num/num.rs | 6 +++--- src/libcore/prelude.rs | 2 +- 6 files changed, 5 insertions(+), 11 deletions(-) (limited to 'src/libcore/num/float.rs') diff --git a/src/libcore/core.rc b/src/libcore/core.rc index bf92a30f7ce..979a02d9f9c 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -105,7 +105,7 @@ pub use iter::{ExtendedMutableIter}; pub use num::{Num, NumCast}; pub use num::{Orderable, Signed, Unsigned, Round}; -pub use num::{Algebraic, Trigonometric, Exponential, Hyperbolic}; +pub use num::{Algebraic, Trigonometric, Exponential}; 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 e687f482fa9..8c34219ae21 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -425,9 +425,7 @@ impl Exponential for f32 { #[inline(always)] fn log10(&self) -> f32 { log10(*self) } -} -impl Hyperbolic for f32 { #[inline(always)] fn sinh(&self) -> f32 { sinh(*self) } diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs index d00e6ae2c0d..19951ad7cff 100644 --- a/src/libcore/num/f64.rs +++ b/src/libcore/num/f64.rs @@ -437,9 +437,7 @@ impl Exponential for f64 { #[inline(always)] fn log10(&self) -> f64 { log10(*self) } -} -impl Hyperbolic for f64 { #[inline(always)] fn sinh(&self) -> f64 { sinh(*self) } diff --git a/src/libcore/num/float.rs b/src/libcore/num/float.rs index 3aa8848cdbe..c64f36f065f 100644 --- a/src/libcore/num/float.rs +++ b/src/libcore/num/float.rs @@ -547,9 +547,7 @@ impl Exponential for float { 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 diff --git a/src/libcore/num/num.rs b/src/libcore/num/num.rs index 3e43ebfef12..30a1213f7ff 100644 --- a/src/libcore/num/num.rs +++ b/src/libcore/num/num.rs @@ -131,9 +131,9 @@ pub trait Exponential { fn log(&self) -> Self; fn log2(&self) -> Self; fn log10(&self) -> Self; -} -pub trait Hyperbolic: Exponential { + // The Hyperbolic Functions are trivially implemented in terms of `exp`, so it's simpler + // to group them within this trait. In the future these would have default implementations. fn sinh(&self) -> Self; fn cosh(&self) -> Self; fn tanh(&self) -> Self; @@ -146,7 +146,7 @@ pub trait Real: Signed + Fractional + Algebraic + Trigonometric - + Hyperbolic { + + Exponential { // Common Constants // FIXME (#5527): These should be associated constants fn pi() -> Self; diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs index 5fef01e65de..1b20efe0cca 100644 --- a/src/libcore/prelude.rs +++ b/src/libcore/prelude.rs @@ -39,7 +39,7 @@ pub use iter::{CopyableIter, CopyableOrderedIter, CopyableNonstrictIter}; pub use iter::{Times, ExtendedMutableIter}; pub use num::{Num, NumCast}; pub use num::{Orderable, Signed, Unsigned, Round}; -pub use num::{Algebraic, Trigonometric, Exponential, Hyperbolic}; +pub use num::{Algebraic, Trigonometric, Exponential}; pub use num::{Integer, Fractional, Real, RealExt}; pub use num::{Bitwise, BitCount, Bounded}; pub use num::{Primitive, Int, Float}; -- cgit 1.4.1-3-g733a5 From 500078e147e1e5f5cf9bd57459ebbdda652d97ed Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Mon, 29 Apr 2013 23:38:58 +1000 Subject: Revert "Merge Exponential and Hyperbolic traits" After discussions on IRC and #4819, we have decided to revert this change. This is due to the traits expressing different ideas and because hyperbolic functions are not trivially implementable from exponential functions for floating-point types. --- src/libcore/core.rc | 2 +- src/libcore/num/f32.rs | 2 ++ src/libcore/num/f64.rs | 2 ++ src/libcore/num/float.rs | 2 ++ src/libcore/num/num.rs | 6 +++--- src/libcore/prelude.rs | 2 +- 6 files changed, 11 insertions(+), 5 deletions(-) (limited to 'src/libcore/num/float.rs') diff --git a/src/libcore/core.rc b/src/libcore/core.rc index 979a02d9f9c..bf92a30f7ce 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -105,7 +105,7 @@ pub use iter::{ExtendedMutableIter}; pub use num::{Num, NumCast}; pub use num::{Orderable, Signed, Unsigned, Round}; -pub use num::{Algebraic, Trigonometric, Exponential}; +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 8c34219ae21..e687f482fa9 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -425,7 +425,9 @@ impl Exponential for f32 { #[inline(always)] fn log10(&self) -> f32 { log10(*self) } +} +impl Hyperbolic for f32 { #[inline(always)] fn sinh(&self) -> f32 { sinh(*self) } diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs index 19951ad7cff..d00e6ae2c0d 100644 --- a/src/libcore/num/f64.rs +++ b/src/libcore/num/f64.rs @@ -437,7 +437,9 @@ impl Exponential for f64 { #[inline(always)] fn log10(&self) -> f64 { log10(*self) } +} +impl Hyperbolic for f64 { #[inline(always)] fn sinh(&self) -> f64 { sinh(*self) } diff --git a/src/libcore/num/float.rs b/src/libcore/num/float.rs index c64f36f065f..3aa8848cdbe 100644 --- a/src/libcore/num/float.rs +++ b/src/libcore/num/float.rs @@ -547,7 +547,9 @@ impl Exponential for float { 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 diff --git a/src/libcore/num/num.rs b/src/libcore/num/num.rs index 30a1213f7ff..3e43ebfef12 100644 --- a/src/libcore/num/num.rs +++ b/src/libcore/num/num.rs @@ -131,9 +131,9 @@ pub trait Exponential { fn log(&self) -> Self; fn log2(&self) -> Self; fn log10(&self) -> Self; +} - // The Hyperbolic Functions are trivially implemented in terms of `exp`, so it's simpler - // to group them within this trait. In the future these would have default implementations. +pub trait Hyperbolic: Exponential { fn sinh(&self) -> Self; fn cosh(&self) -> Self; fn tanh(&self) -> Self; @@ -146,7 +146,7 @@ pub trait Real: Signed + Fractional + Algebraic + Trigonometric - + Exponential { + + Hyperbolic { // Common Constants // FIXME (#5527): These should be associated constants fn pi() -> Self; diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs index 1b20efe0cca..5fef01e65de 100644 --- a/src/libcore/prelude.rs +++ b/src/libcore/prelude.rs @@ -39,7 +39,7 @@ pub use iter::{CopyableIter, CopyableOrderedIter, CopyableNonstrictIter}; pub use iter::{Times, ExtendedMutableIter}; pub use num::{Num, NumCast}; pub use num::{Orderable, Signed, Unsigned, Round}; -pub use num::{Algebraic, Trigonometric, Exponential}; +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}; -- cgit 1.4.1-3-g733a5