diff options
| author | bors <bors@rust-lang.org> | 2013-04-29 13:39:37 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-04-29 13:39:37 -0700 |
| commit | dbcc3fe63a71d92d194d99dfd5e73fb62d09e79a (patch) | |
| tree | 642f815ad0d6a4043531bb0bfa521e459febaf50 /src | |
| parent | 76ec35ae743ee299484a48b233bc64cf3779097d (diff) | |
| parent | 500078e147e1e5f5cf9bd57459ebbdda652d97ed (diff) | |
| download | rust-dbcc3fe63a71d92d194d99dfd5e73fb62d09e79a.tar.gz rust-dbcc3fe63a71d92d194d99dfd5e73fb62d09e79a.zip | |
auto merge of #6110 : bjz/rust/numeric-traits, r=pcwalton
As discussed on issue #4819, 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`.
Diffstat (limited to 'src')
| -rw-r--r-- | src/libcore/core.rc | 5 | ||||
| -rw-r--r-- | src/libcore/num/f32.rs | 142 | ||||
| -rw-r--r-- | src/libcore/num/f64.rs | 140 | ||||
| -rw-r--r-- | src/libcore/num/float.rs | 179 | ||||
| -rw-r--r-- | src/libcore/num/int-template.rs | 40 | ||||
| -rw-r--r-- | src/libcore/num/num.rs | 76 | ||||
| -rw-r--r-- | src/libcore/num/uint-template.rs | 29 | ||||
| -rw-r--r-- | src/libcore/prelude.rs | 5 | ||||
| -rw-r--r-- | src/libstd/num/bigint.rs | 4 | ||||
| -rw-r--r-- | src/libstd/num/rational.rs | 18 |
10 files changed, 380 insertions, 258 deletions
diff --git a/src/libcore/core.rc b/src/libcore/core.rc index dc3cd03dc20..f9a56f613d5 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -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}; 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,154 +367,153 @@ impl Fractional for f32 { fn recip(&self) -> f32 { 1.0 / *self } } -impl Real for f32 { - /// Archimedes' constant +impl Algebraic for f32 { #[inline(always)] - fn pi() -> f32 { 3.14159265358979323846264338327950288 } - - /// 2.0 * pi - #[inline(always)] - fn two_pi() -> f32 { 6.28318530717958647692528676655900576 } - - /// pi / 2.0 - #[inline(always)] - fn frac_pi_2() -> f32 { 1.57079632679489661923132169163975144 } - - /// pi / 3.0 - #[inline(always)] - fn frac_pi_3() -> f32 { 1.04719755119659774615421446109316763 } + fn pow(&self, n: f32) -> f32 { pow(*self, n) } - /// pi / 4.0 #[inline(always)] - fn frac_pi_4() -> f32 { 0.785398163397448309615660845819875721 } + fn sqrt(&self) -> f32 { sqrt(*self) } - /// pi / 6.0 #[inline(always)] - fn frac_pi_6() -> f32 { 0.52359877559829887307710723054658381 } + fn rsqrt(&self) -> f32 { self.sqrt().recip() } - /// pi / 8.0 #[inline(always)] - fn frac_pi_8() -> f32 { 0.39269908169872415480783042290993786 } + fn cbrt(&self) -> f32 { cbrt(*self) } - /// 1 .0/ pi #[inline(always)] - fn frac_1_pi() -> f32 { 0.318309886183790671537767526745028724 } + fn hypot(&self, other: f32) -> f32 { hypot(*self, other) } +} - /// 2.0 / pi +impl Trigonometric for f32 { #[inline(always)] - fn frac_2_pi() -> f32 { 0.636619772367581343075535053490057448 } + fn sin(&self) -> f32 { sin(*self) } - /// 2.0 / sqrt(pi) #[inline(always)] - fn frac_2_sqrtpi() -> f32 { 1.12837916709551257389615890312154517 } + fn cos(&self) -> f32 { cos(*self) } - /// sqrt(2.0) #[inline(always)] - fn sqrt2() -> f32 { 1.41421356237309504880168872420969808 } + fn tan(&self) -> f32 { tan(*self) } - /// 1.0 / sqrt(2.0) #[inline(always)] - fn frac_1_sqrt2() -> f32 { 0.707106781186547524400844362104849039 } + fn asin(&self) -> f32 { asin(*self) } - /// Euler's number #[inline(always)] - fn e() -> f32 { 2.71828182845904523536028747135266250 } + fn acos(&self) -> f32 { acos(*self) } - /// log2(e) #[inline(always)] - fn log2_e() -> f32 { 1.44269504088896340735992468100189214 } + fn atan(&self) -> f32 { atan(*self) } - /// log10(e) #[inline(always)] - fn log10_e() -> f32 { 0.434294481903251827651128918916605082 } + fn atan2(&self, other: f32) -> f32 { atan2(*self, other) } +} - /// log(2.0) +impl Exponential for f32 { #[inline(always)] - fn log_2() -> f32 { 0.693147180559945309417232121458176568 } + fn exp(&self) -> f32 { exp(*self) } - /// log(10.0) #[inline(always)] - fn log_10() -> f32 { 2.30258509299404568401799145468436421 } + fn exp2(&self) -> f32 { exp2(*self) } #[inline(always)] - fn pow(&self, n: f32) -> f32 { pow(*self, n) } + fn expm1(&self) -> f32 { expm1(*self) } #[inline(always)] - fn exp(&self) -> f32 { exp(*self) } + fn log(&self) -> f32 { ln(*self) } #[inline(always)] - fn exp2(&self) -> f32 { exp2(*self) } + fn log2(&self) -> f32 { log2(*self) } #[inline(always)] - fn expm1(&self) -> f32 { expm1(*self) } + fn log10(&self) -> f32 { log10(*self) } +} +impl Hyperbolic for f32 { #[inline(always)] - fn ldexp(&self, n: int) -> f32 { ldexp(*self, n as c_int) } + fn sinh(&self) -> f32 { sinh(*self) } #[inline(always)] - fn log(&self) -> f32 { ln(*self) } + fn cosh(&self) -> f32 { cosh(*self) } #[inline(always)] - fn log2(&self) -> f32 { log2(*self) } + fn tanh(&self) -> f32 { tanh(*self) } +} +impl Real for f32 { + /// Archimedes' constant #[inline(always)] - fn log10(&self) -> f32 { log10(*self) } + fn pi() -> f32 { 3.14159265358979323846264338327950288 } + /// 2.0 * pi #[inline(always)] - fn log_radix(&self) -> f32 { log_radix(*self) as f32 } + fn two_pi() -> f32 { 6.28318530717958647692528676655900576 } + /// pi / 2.0 #[inline(always)] - fn ilog_radix(&self) -> int { ilog_radix(*self) as int } + fn frac_pi_2() -> f32 { 1.57079632679489661923132169163975144 } + /// pi / 3.0 #[inline(always)] - fn sqrt(&self) -> f32 { sqrt(*self) } + fn frac_pi_3() -> f32 { 1.04719755119659774615421446109316763 } + /// pi / 4.0 #[inline(always)] - fn rsqrt(&self) -> f32 { self.sqrt().recip() } + fn frac_pi_4() -> f32 { 0.785398163397448309615660845819875721 } + /// pi / 6.0 #[inline(always)] - fn cbrt(&self) -> f32 { cbrt(*self) } + fn frac_pi_6() -> f32 { 0.52359877559829887307710723054658381 } - /// Converts to degrees, assuming the number is in radians + /// pi / 8.0 #[inline(always)] - fn to_degrees(&self) -> f32 { *self * (180.0 / Real::pi::<f32>()) } + fn frac_pi_8() -> f32 { 0.39269908169872415480783042290993786 } - /// Converts to radians, assuming the number is in degrees + /// 1 .0/ pi #[inline(always)] - fn to_radians(&self) -> f32 { *self * (Real::pi::<f32>() / 180.0) } + fn frac_1_pi() -> f32 { 0.318309886183790671537767526745028724 } + /// 2.0 / pi #[inline(always)] - fn hypot(&self, other: f32) -> f32 { hypot(*self, other) } + fn frac_2_pi() -> f32 { 0.636619772367581343075535053490057448 } + /// 2.0 / sqrt(pi) #[inline(always)] - fn sin(&self) -> f32 { sin(*self) } + fn frac_2_sqrtpi() -> f32 { 1.12837916709551257389615890312154517 } + /// sqrt(2.0) #[inline(always)] - fn cos(&self) -> f32 { cos(*self) } + fn sqrt2() -> f32 { 1.41421356237309504880168872420969808 } + /// 1.0 / sqrt(2.0) #[inline(always)] - fn tan(&self) -> f32 { tan(*self) } + fn frac_1_sqrt2() -> f32 { 0.707106781186547524400844362104849039 } + /// Euler's number #[inline(always)] - fn asin(&self) -> f32 { asin(*self) } + fn e() -> f32 { 2.71828182845904523536028747135266250 } + /// log2(e) #[inline(always)] - fn acos(&self) -> f32 { acos(*self) } + fn log2_e() -> f32 { 1.44269504088896340735992468100189214 } + /// log10(e) #[inline(always)] - fn atan(&self) -> f32 { atan(*self) } + fn log10_e() -> f32 { 0.434294481903251827651128918916605082 } + /// log(2.0) #[inline(always)] - fn atan2(&self, other: f32) -> f32 { atan2(*self, other) } + fn log_2() -> f32 { 0.693147180559945309417232121458176568 } + /// log(10.0) #[inline(always)] - fn sinh(&self) -> f32 { sinh(*self) } + fn log_10() -> f32 { 2.30258509299404568401799145468436421 } + /// Converts to degrees, assuming the number is in radians #[inline(always)] - fn cosh(&self) -> f32 { cosh(*self) } + fn to_degrees(&self) -> f32 { *self * (180.0 / Real::pi::<f32>()) } + /// Converts to radians, assuming the number is in degrees #[inline(always)] - fn tanh(&self) -> f32 { tanh(*self) } + fn to_radians(&self) -> f32 { *self * (Real::pi::<f32>() / 180.0) } } 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,154 +379,153 @@ impl Fractional for f64 { fn recip(&self) -> f64 { 1.0 / *self } } -impl Real for f64 { - /// Archimedes' constant +impl Algebraic for f64 { #[inline(always)] - fn pi() -> f64 { 3.14159265358979323846264338327950288 } - - /// 2.0 * pi - #[inline(always)] - fn two_pi() -> f64 { 6.28318530717958647692528676655900576 } - - /// pi / 2.0 - #[inline(always)] - fn frac_pi_2() -> f64 { 1.57079632679489661923132169163975144 } + fn pow(&self, n: f64) -> f64 { pow(*self, n) } - /// pi / 3.0 #[inline(always)] - fn frac_pi_3() -> f64 { 1.04719755119659774615421446109316763 } - - /// pi / 4.0 - #[inline(always)] - fn frac_pi_4() -> f64 { 0.785398163397448309615660845819875721 } + fn sqrt(&self) -> f64 { sqrt(*self) } - /// pi / 6.0 #[inline(always)] - fn frac_pi_6() -> f64 { 0.52359877559829887307710723054658381 } + fn rsqrt(&self) -> f64 { self.sqrt().recip() } - /// pi / 8.0 #[inline(always)] - fn frac_pi_8() -> f64 { 0.39269908169872415480783042290993786 } + fn cbrt(&self) -> f64 { cbrt(*self) } - /// 1.0 / pi #[inline(always)] - fn frac_1_pi() -> f64 { 0.318309886183790671537767526745028724 } + fn hypot(&self, other: f64) -> f64 { hypot(*self, other) } +} - /// 2.0 / pi +impl Trigonometric for f64 { #[inline(always)] - fn frac_2_pi() -> f64 { 0.636619772367581343075535053490057448 } + fn sin(&self) -> f64 { sin(*self) } - /// 2.0 / sqrt(pi) #[inline(always)] - fn frac_2_sqrtpi() -> f64 { 1.12837916709551257389615890312154517 } + fn cos(&self) -> f64 { cos(*self) } - /// sqrt(2.0) #[inline(always)] - fn sqrt2() -> f64 { 1.41421356237309504880168872420969808 } + fn tan(&self) -> f64 { tan(*self) } - /// 1.0 / sqrt(2.0) #[inline(always)] - fn frac_1_sqrt2() -> f64 { 0.707106781186547524400844362104849039 } + fn asin(&self) -> f64 { asin(*self) } - /// Euler's number #[inline(always)] - fn e() -> f64 { 2.71828182845904523536028747135266250 } + fn acos(&self) -> f64 { acos(*self) } - /// log2(e) #[inline(always)] - fn log2_e() -> f64 { 1.44269504088896340735992468100189214 } + fn atan(&self) -> f64 { atan(*self) } - /// log10(e) #[inline(always)] - fn log10_e() -> f64 { 0.434294481903251827651128918916605082 } + fn atan2(&self, other: f64) -> f64 { atan2(*self, other) } +} - /// log(2.0) +impl Exponential for f64 { #[inline(always)] - fn log_2() -> f64 { 0.693147180559945309417232121458176568 } + fn exp(&self) -> f64 { exp(*self) } - /// log(10.0) #[inline(always)] - fn log_10() -> f64 { 2.30258509299404568401799145468436421 } + fn exp2(&self) -> f64 { exp2(*self) } #[inline(always)] - fn pow(&self, n: f64) -> f64 { pow(*self, n) } + fn expm1(&self) -> f64 { expm1(*self) } #[inline(always)] - fn exp(&self) -> f64 { exp(*self) } + fn log(&self) -> f64 { ln(*self) } #[inline(always)] - fn exp2(&self) -> f64 { exp2(*self) } + fn log2(&self) -> f64 { log2(*self) } #[inline(always)] - fn expm1(&self) -> f64 { expm1(*self) } + fn log10(&self) -> f64 { log10(*self) } +} +impl Hyperbolic for f64 { #[inline(always)] - fn ldexp(&self, n: int) -> f64 { ldexp(*self, n as c_int) } + fn sinh(&self) -> f64 { sinh(*self) } #[inline(always)] - fn log(&self) -> f64 { ln(*self) } + fn cosh(&self) -> f64 { cosh(*self) } #[inline(always)] - fn log2(&self) -> f64 { log2(*self) } + fn tanh(&self) -> f64 { tanh(*self) } +} +impl Real for f64 { + /// Archimedes' constant #[inline(always)] - fn log10(&self) -> f64 { log10(*self) } + fn pi() -> f64 { 3.14159265358979323846264338327950288 } + /// 2.0 * pi #[inline(always)] - fn log_radix(&self) -> f64 { log_radix(*self) } + fn two_pi() -> f64 { 6.28318530717958647692528676655900576 } + /// pi / 2.0 #[inline(always)] - fn ilog_radix(&self) -> int { ilog_radix(*self) as int } + fn frac_pi_2() -> f64 { 1.57079632679489661923132169163975144 } + /// pi / 3.0 #[inline(always)] - fn sqrt(&self) -> f64 { sqrt(*self) } + fn frac_pi_3() -> f64 { 1.04719755119659774615421446109316763 } + /// pi / 4.0 #[inline(always)] - fn rsqrt(&self) -> f64 { self.sqrt().recip() } + fn frac_pi_4() -> f64 { 0.785398163397448309615660845819875721 } + /// pi / 6.0 #[inline(always)] - fn cbrt(&self) -> f64 { cbrt(*self) } + fn frac_pi_6() -> f64 { 0.52359877559829887307710723054658381 } - /// Converts to degrees, assuming the number is in radians + /// pi / 8.0 #[inline(always)] - fn to_degrees(&self) -> f64 { *self * (180.0 / Real::pi::<f64>()) } + fn frac_pi_8() -> f64 { 0.39269908169872415480783042290993786 } - /// Converts to radians, assuming the number is in degrees + /// 1.0 / pi #[inline(always)] - fn to_radians(&self) -> f64 { *self * (Real::pi::<f64>() / 180.0) } + fn frac_1_pi() -> f64 { 0.318309886183790671537767526745028724 } + /// 2.0 / pi #[inline(always)] - fn hypot(&self, other: f64) -> f64 { hypot(*self, other) } + fn frac_2_pi() -> f64 { 0.636619772367581343075535053490057448 } + /// 2.0 / sqrt(pi) #[inline(always)] - fn sin(&self) -> f64 { sin(*self) } + fn frac_2_sqrtpi() -> f64 { 1.12837916709551257389615890312154517 } + /// sqrt(2.0) #[inline(always)] - fn cos(&self) -> f64 { cos(*self) } + fn sqrt2() -> f64 { 1.41421356237309504880168872420969808 } + /// 1.0 / sqrt(2.0) #[inline(always)] - fn tan(&self) -> f64 { tan(*self) } + fn frac_1_sqrt2() -> f64 { 0.707106781186547524400844362104849039 } + /// Euler's number #[inline(always)] - fn asin(&self) -> f64 { asin(*self) } + fn e() -> f64 { 2.71828182845904523536028747135266250 } + /// log2(e) #[inline(always)] - fn acos(&self) -> f64 { acos(*self) } + fn log2_e() -> f64 { 1.44269504088896340735992468100189214 } + /// log10(e) #[inline(always)] - fn atan(&self) -> f64 { atan(*self) } + fn log10_e() -> f64 { 0.434294481903251827651128918916605082 } + /// log(2.0) #[inline(always)] - fn atan2(&self, other: f64) -> f64 { atan2(*self, other) } + fn log_2() -> f64 { 0.693147180559945309417232121458176568 } + /// log(10.0) #[inline(always)] - fn sinh(&self) -> f64 { sinh(*self) } + fn log_10() -> f64 { 2.30258509299404568401799145468436421 } + /// Converts to degrees, assuming the number is in radians #[inline(always)] - fn cosh(&self) -> f64 { cosh(*self) } + fn to_degrees(&self) -> f64 { *self * (180.0 / Real::pi::<f64>()) } + /// Converts to radians, assuming the number is in degrees #[inline(always)] - fn tanh(&self) -> f64 { tanh(*self) } + fn to_radians(&self) -> f64 { *self * (Real::pi::<f64>() / 180.0) } } 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,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::<float>()) } + 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::<float>() / 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 { diff --git a/src/libcore/num/int-template.rs b/src/libcore/num/int-template.rs index 08df820a73d..ec38a32c039 100644 --- a/src/libcore/num/int-template.rs +++ b/src/libcore/num/int-template.rs @@ -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)] @@ -683,6 +683,42 @@ mod tests { } #[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); } diff --git a/src/libcore/num/num.rs b/src/libcore/num/num.rs index 0e2669a26b6..3e43ebfef12 100644 --- a/src/libcore/num/num.rs +++ b/src/libcore/num/num.rs @@ -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; } /// diff --git a/src/libcore/num/uint-template.rs b/src/libcore/num/uint-template.rs index af64660ad0c..3dfdd22c42d 100644 --- a/src/libcore/num/uint-template.rs +++ b/src/libcore/num/uint-template.rs @@ -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)] @@ -416,6 +416,31 @@ mod tests { } #[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))); assert_eq!(0b1000 as T, (0b1100 as T).bitand(&(0b1010 as T))); diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs index 41078fb8920..9a2e480ce6e 100644 --- a/src/libcore/prelude.rs +++ b/src/libcore/prelude.rs @@ -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; diff --git a/src/libstd/num/bigint.rs b/src/libstd/num/bigint.rs index 3ea94eababb..e97b3b5eeec 100644 --- a/src/libstd/num/bigint.rs +++ b/src/libstd/num/bigint.rs @@ -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)] diff --git a/src/libstd/num/rational.rs b/src/libstd/num/rational.rs index 34308988fa5..a7c170c1cd6 100644 --- a/src/libstd/num/rational.rs +++ b/src/libstd/num/rational.rs @@ -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> { @@ -447,6 +456,15 @@ mod test { } #[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) { assert_eq!(FromStr::from_str(s), Some(r)); |
