diff options
| author | bors <bors@rust-lang.org> | 2014-02-17 22:16:51 -0800 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-02-17 22:16:51 -0800 |
| commit | b0ce960609d17823a24469249b1a8b4e6ad9f448 (patch) | |
| tree | 47155529ce8b608797c17346adbed5e161fbde34 /src/libstd | |
| parent | 62d7d0079f1b539231cb8cbb8f6368d2e4be602c (diff) | |
| parent | 876eb931dcdfa1a1e55a58f3af230062727f3c70 (diff) | |
| download | rust-b0ce960609d17823a24469249b1a8b4e6ad9f448.tar.gz rust-b0ce960609d17823a24469249b1a8b4e6ad9f448.zip | |
auto merge of #12321 : bjz/rust/remove-real, r=alexcrichton
This is part of the effort to simplify `std::num`, as tracked in issue #10387. It is also a step towards a proper IEEE-754 trait (see #12281).
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/num/f32.rs | 326 | ||||
| -rw-r--r-- | src/libstd/num/f64.rs | 326 | ||||
| -rw-r--r-- | src/libstd/num/mod.rs | 338 | ||||
| -rw-r--r-- | src/libstd/prelude.rs | 2 | ||||
| -rw-r--r-- | src/libstd/rand/distributions/exponential.rs | 2 | ||||
| -rw-r--r-- | src/libstd/rand/distributions/gamma.rs | 2 | ||||
| -rw-r--r-- | src/libstd/rand/distributions/normal.rs | 2 |
7 files changed, 494 insertions, 504 deletions
diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs index f418be262ed..688e8347d9a 100644 --- a/src/libstd/num/f32.rs +++ b/src/libstd/num/f32.rs @@ -127,7 +127,7 @@ pub mod consts { // staticants from cmath. // FIXME(#11621): These constants should be deprecated once CTFE is - // implemented in favour of calling their respective functions in `Real`. + // implemented in favour of calling their respective functions in `Float`. /// Archimedes' constant pub static PI: f32 = 3.14159265358979323846264338327950288_f32; @@ -300,7 +300,148 @@ impl Round for f32 { fn fract(&self) -> f32 { *self - self.trunc() } } -impl Real for f32 { +impl Bounded for f32 { + #[inline] + fn min_value() -> f32 { 1.17549435e-38 } + + #[inline] + fn max_value() -> f32 { 3.40282347e+38 } +} + +impl Primitive for f32 {} + +impl Float for f32 { + #[inline] + fn nan() -> f32 { 0.0 / 0.0 } + + #[inline] + fn infinity() -> f32 { 1.0 / 0.0 } + + #[inline] + fn neg_infinity() -> f32 { -1.0 / 0.0 } + + #[inline] + fn neg_zero() -> f32 { -0.0 } + + /// Returns `true` if the number is NaN + #[inline] + fn is_nan(&self) -> bool { *self != *self } + + /// Returns `true` if the number is infinite + #[inline] + fn is_infinite(&self) -> bool { + *self == Float::infinity() || *self == Float::neg_infinity() + } + + /// Returns `true` if the number is neither infinite or NaN + #[inline] + fn is_finite(&self) -> bool { + !(self.is_nan() || self.is_infinite()) + } + + /// Returns `true` if the number is neither zero, infinite, subnormal or NaN + #[inline] + fn is_normal(&self) -> bool { + self.classify() == FPNormal + } + + /// Returns the floating point category of the number. If only one property is going to + /// be tested, it is generally faster to use the specific predicate instead. + fn classify(&self) -> FPCategory { + static EXP_MASK: u32 = 0x7f800000; + static MAN_MASK: u32 = 0x007fffff; + + match ( + unsafe { ::cast::transmute::<f32,u32>(*self) } & MAN_MASK, + unsafe { ::cast::transmute::<f32,u32>(*self) } & EXP_MASK, + ) { + (0, 0) => FPZero, + (_, 0) => FPSubnormal, + (0, EXP_MASK) => FPInfinite, + (_, EXP_MASK) => FPNaN, + _ => FPNormal, + } + } + + #[inline] + fn mantissa_digits(_: Option<f32>) -> uint { 24 } + + #[inline] + fn digits(_: Option<f32>) -> uint { 6 } + + #[inline] + fn epsilon() -> f32 { 1.19209290e-07 } + + #[inline] + fn min_exp(_: Option<f32>) -> int { -125 } + + #[inline] + fn max_exp(_: Option<f32>) -> int { 128 } + + #[inline] + fn min_10_exp(_: Option<f32>) -> int { -37 } + + #[inline] + fn max_10_exp(_: Option<f32>) -> int { 38 } + + /// Constructs a floating point number by multiplying `x` by 2 raised to the power of `exp` + #[inline] + fn ldexp(x: f32, exp: int) -> f32 { + ldexp(x, exp as c_int) + } + + /// Breaks the number into a normalized fraction and a base-2 exponent, satisfying: + /// + /// - `self = x * pow(2, exp)` + /// - `0.5 <= abs(x) < 1.0` + #[inline] + fn frexp(&self) -> (f32, int) { + let mut exp = 0; + let x = frexp(*self, &mut exp); + (x, exp as int) + } + + /// Returns the exponential of the number, minus `1`, in a way that is accurate + /// even if the number is close to zero + #[inline] + fn exp_m1(&self) -> f32 { exp_m1(*self) } + + /// Returns the natural logarithm of the number plus `1` (`ln(1+n)`) more accurately + /// than if the operations were performed separately + #[inline] + fn ln_1p(&self) -> f32 { ln_1p(*self) } + + /// Fused multiply-add. Computes `(self * a) + b` with only one rounding error. This + /// produces a more accurate result with better performance than a separate multiplication + /// operation followed by an add. + #[inline] + fn mul_add(&self, a: f32, b: f32) -> f32 { + mul_add(*self, a, b) + } + + /// Returns the next representable floating-point value in the direction of `other` + #[inline] + fn next_after(&self, other: f32) -> f32 { + next_after(*self, other) + } + + /// Returns the mantissa, exponent and sign as integers. + fn integer_decode(&self) -> (u64, i16, i8) { + let bits: u32 = unsafe { + ::cast::transmute(*self) + }; + let sign: i8 = if bits >> 31 == 0 { 1 } else { -1 }; + let mut exponent: i16 = ((bits >> 23) & 0xff) as i16; + let mantissa = if exponent == 0 { + (bits & 0x7fffff) << 1 + } else { + (bits & 0x7fffff) | 0x800000 + }; + // Exponent bias + mantissa shift + exponent -= 127 + 23; + (mantissa as u64, exponent, sign) + } + /// Archimedes' constant #[inline] fn pi() -> f32 { 3.14159265358979323846264338327950288 } @@ -495,159 +636,16 @@ impl Real for f32 { /// Converts to degrees, assuming the number is in radians #[inline] - fn to_degrees(&self) -> f32 { *self * (180.0f32 / Real::pi()) } + fn to_degrees(&self) -> f32 { *self * (180.0f32 / Float::pi()) } /// Converts to radians, assuming the number is in degrees #[inline] fn to_radians(&self) -> f32 { - let value: f32 = Real::pi(); + let value: f32 = Float::pi(); *self * (value / 180.0f32) } } -impl Bounded for f32 { - #[inline] - fn min_value() -> f32 { 1.17549435e-38 } - - #[inline] - fn max_value() -> f32 { 3.40282347e+38 } -} - -impl Primitive for f32 {} - -impl Float for f32 { - #[inline] - fn nan() -> f32 { 0.0 / 0.0 } - - #[inline] - fn infinity() -> f32 { 1.0 / 0.0 } - - #[inline] - fn neg_infinity() -> f32 { -1.0 / 0.0 } - - #[inline] - fn neg_zero() -> f32 { -0.0 } - - /// Returns `true` if the number is NaN - #[inline] - fn is_nan(&self) -> bool { *self != *self } - - /// Returns `true` if the number is infinite - #[inline] - fn is_infinite(&self) -> bool { - *self == Float::infinity() || *self == Float::neg_infinity() - } - - /// Returns `true` if the number is neither infinite or NaN - #[inline] - fn is_finite(&self) -> bool { - !(self.is_nan() || self.is_infinite()) - } - - /// Returns `true` if the number is neither zero, infinite, subnormal or NaN - #[inline] - fn is_normal(&self) -> bool { - self.classify() == FPNormal - } - - /// Returns the floating point category of the number. If only one property is going to - /// be tested, it is generally faster to use the specific predicate instead. - fn classify(&self) -> FPCategory { - static EXP_MASK: u32 = 0x7f800000; - static MAN_MASK: u32 = 0x007fffff; - - match ( - unsafe { ::cast::transmute::<f32,u32>(*self) } & MAN_MASK, - unsafe { ::cast::transmute::<f32,u32>(*self) } & EXP_MASK, - ) { - (0, 0) => FPZero, - (_, 0) => FPSubnormal, - (0, EXP_MASK) => FPInfinite, - (_, EXP_MASK) => FPNaN, - _ => FPNormal, - } - } - - #[inline] - fn mantissa_digits(_: Option<f32>) -> uint { 24 } - - #[inline] - fn digits(_: Option<f32>) -> uint { 6 } - - #[inline] - fn epsilon() -> f32 { 1.19209290e-07 } - - #[inline] - fn min_exp(_: Option<f32>) -> int { -125 } - - #[inline] - fn max_exp(_: Option<f32>) -> int { 128 } - - #[inline] - fn min_10_exp(_: Option<f32>) -> int { -37 } - - #[inline] - fn max_10_exp(_: Option<f32>) -> int { 38 } - - /// Constructs a floating point number by multiplying `x` by 2 raised to the power of `exp` - #[inline] - fn ldexp(x: f32, exp: int) -> f32 { - ldexp(x, exp as c_int) - } - - /// Breaks the number into a normalized fraction and a base-2 exponent, satisfying: - /// - /// - `self = x * pow(2, exp)` - /// - `0.5 <= abs(x) < 1.0` - #[inline] - fn frexp(&self) -> (f32, int) { - let mut exp = 0; - let x = frexp(*self, &mut exp); - (x, exp as int) - } - - /// Returns the exponential of the number, minus `1`, in a way that is accurate - /// even if the number is close to zero - #[inline] - fn exp_m1(&self) -> f32 { exp_m1(*self) } - - /// Returns the natural logarithm of the number plus `1` (`ln(1+n)`) more accurately - /// than if the operations were performed separately - #[inline] - fn ln_1p(&self) -> f32 { ln_1p(*self) } - - /// Fused multiply-add. Computes `(self * a) + b` with only one rounding error. This - /// produces a more accurate result with better performance than a separate multiplication - /// operation followed by an add. - #[inline] - fn mul_add(&self, a: f32, b: f32) -> f32 { - mul_add(*self, a, b) - } - - /// Returns the next representable floating-point value in the direction of `other` - #[inline] - fn next_after(&self, other: f32) -> f32 { - next_after(*self, other) - } - - /// Returns the mantissa, exponent and sign as integers. - fn integer_decode(&self) -> (u64, i16, i8) { - let bits: u32 = unsafe { - ::cast::transmute(*self) - }; - let sign: i8 = if bits >> 31 == 0 { 1 } else { -1 }; - let mut exponent: i16 = ((bits >> 23) & 0xff) as i16; - let mantissa = if exponent == 0 { - (bits & 0x7fffff) << 1 - } else { - (bits & 0x7fffff) | 0x800000 - }; - // Exponent bias + mantissa shift - exponent -= 127 + 23; - (mantissa as u64, exponent, sign) - } -} - // // Section: String Conversions // @@ -1002,23 +1000,23 @@ mod tests { #[test] fn test_real_consts() { - let pi: f32 = Real::pi(); - let two_pi: f32 = Real::two_pi(); - let frac_pi_2: f32 = Real::frac_pi_2(); - let frac_pi_3: f32 = Real::frac_pi_3(); - let frac_pi_4: f32 = Real::frac_pi_4(); - let frac_pi_6: f32 = Real::frac_pi_6(); - let frac_pi_8: f32 = Real::frac_pi_8(); - let frac_1_pi: f32 = Real::frac_1_pi(); - let frac_2_pi: f32 = Real::frac_2_pi(); - let frac_2_sqrtpi: f32 = Real::frac_2_sqrtpi(); - let sqrt2: f32 = Real::sqrt2(); - let frac_1_sqrt2: f32 = Real::frac_1_sqrt2(); - let e: f32 = Real::e(); - let log2_e: f32 = Real::log2_e(); - let log10_e: f32 = Real::log10_e(); - let ln_2: f32 = Real::ln_2(); - let ln_10: f32 = Real::ln_10(); + let pi: f32 = Float::pi(); + let two_pi: f32 = Float::two_pi(); + let frac_pi_2: f32 = Float::frac_pi_2(); + let frac_pi_3: f32 = Float::frac_pi_3(); + let frac_pi_4: f32 = Float::frac_pi_4(); + let frac_pi_6: f32 = Float::frac_pi_6(); + let frac_pi_8: f32 = Float::frac_pi_8(); + let frac_1_pi: f32 = Float::frac_1_pi(); + let frac_2_pi: f32 = Float::frac_2_pi(); + let frac_2_sqrtpi: f32 = Float::frac_2_sqrtpi(); + let sqrt2: f32 = Float::sqrt2(); + let frac_1_sqrt2: f32 = Float::frac_1_sqrt2(); + let e: f32 = Float::e(); + let log2_e: f32 = Float::log2_e(); + let log10_e: f32 = Float::log10_e(); + let ln_2: f32 = Float::ln_2(); + let ln_10: f32 = Float::ln_10(); assert_approx_eq!(two_pi, 2f32 * pi); assert_approx_eq!(frac_pi_2, pi / 2f32); diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs index 1b1aaf68470..dafb3187ff8 100644 --- a/src/libstd/num/f64.rs +++ b/src/libstd/num/f64.rs @@ -134,7 +134,7 @@ pub mod consts { // constants from cmath. // FIXME(#11621): These constants should be deprecated once CTFE is - // implemented in favour of calling their respective functions in `Real`. + // implemented in favour of calling their respective functions in `Float`. /// Archimedes' constant pub static PI: f64 = 3.14159265358979323846264338327950288_f64; @@ -302,7 +302,148 @@ impl Round for f64 { fn fract(&self) -> f64 { *self - self.trunc() } } -impl Real for f64 { +impl Bounded for f64 { + #[inline] + fn min_value() -> f64 { 2.2250738585072014e-308 } + + #[inline] + fn max_value() -> f64 { 1.7976931348623157e+308 } +} + +impl Primitive for f64 {} + +impl Float for f64 { + #[inline] + fn nan() -> f64 { 0.0 / 0.0 } + + #[inline] + fn infinity() -> f64 { 1.0 / 0.0 } + + #[inline] + fn neg_infinity() -> f64 { -1.0 / 0.0 } + + #[inline] + fn neg_zero() -> f64 { -0.0 } + + /// Returns `true` if the number is NaN + #[inline] + fn is_nan(&self) -> bool { *self != *self } + + /// Returns `true` if the number is infinite + #[inline] + fn is_infinite(&self) -> bool { + *self == Float::infinity() || *self == Float::neg_infinity() + } + + /// Returns `true` if the number is neither infinite or NaN + #[inline] + fn is_finite(&self) -> bool { + !(self.is_nan() || self.is_infinite()) + } + + /// Returns `true` if the number is neither zero, infinite, subnormal or NaN + #[inline] + fn is_normal(&self) -> bool { + self.classify() == FPNormal + } + + /// Returns the floating point category of the number. If only one property is going to + /// be tested, it is generally faster to use the specific predicate instead. + fn classify(&self) -> FPCategory { + static EXP_MASK: u64 = 0x7ff0000000000000; + static MAN_MASK: u64 = 0x000fffffffffffff; + + match ( + unsafe { ::cast::transmute::<f64,u64>(*self) } & MAN_MASK, + unsafe { ::cast::transmute::<f64,u64>(*self) } & EXP_MASK, + ) { + (0, 0) => FPZero, + (_, 0) => FPSubnormal, + (0, EXP_MASK) => FPInfinite, + (_, EXP_MASK) => FPNaN, + _ => FPNormal, + } + } + + #[inline] + fn mantissa_digits(_: Option<f64>) -> uint { 53 } + + #[inline] + fn digits(_: Option<f64>) -> uint { 15 } + + #[inline] + fn epsilon() -> f64 { 2.2204460492503131e-16 } + + #[inline] + fn min_exp(_: Option<f64>) -> int { -1021 } + + #[inline] + fn max_exp(_: Option<f64>) -> int { 1024 } + + #[inline] + fn min_10_exp(_: Option<f64>) -> int { -307 } + + #[inline] + fn max_10_exp(_: Option<f64>) -> int { 308 } + + /// Constructs a floating point number by multiplying `x` by 2 raised to the power of `exp` + #[inline] + fn ldexp(x: f64, exp: int) -> f64 { + ldexp(x, exp as c_int) + } + + /// Breaks the number into a normalized fraction and a base-2 exponent, satisfying: + /// + /// - `self = x * pow(2, exp)` + /// - `0.5 <= abs(x) < 1.0` + #[inline] + fn frexp(&self) -> (f64, int) { + let mut exp = 0; + let x = frexp(*self, &mut exp); + (x, exp as int) + } + + /// Returns the exponential of the number, minus `1`, in a way that is accurate + /// even if the number is close to zero + #[inline] + fn exp_m1(&self) -> f64 { exp_m1(*self) } + + /// Returns the natural logarithm of the number plus `1` (`ln(1+n)`) more accurately + /// than if the operations were performed separately + #[inline] + fn ln_1p(&self) -> f64 { ln_1p(*self) } + + /// Fused multiply-add. Computes `(self * a) + b` with only one rounding error. This + /// produces a more accurate result with better performance than a separate multiplication + /// operation followed by an add. + #[inline] + fn mul_add(&self, a: f64, b: f64) -> f64 { + mul_add(*self, a, b) + } + + /// Returns the next representable floating-point value in the direction of `other` + #[inline] + fn next_after(&self, other: f64) -> f64 { + next_after(*self, other) + } + + /// Returns the mantissa, exponent and sign as integers. + fn integer_decode(&self) -> (u64, i16, i8) { + let bits: u64 = unsafe { + ::cast::transmute(*self) + }; + let sign: i8 = if bits >> 63 == 0 { 1 } else { -1 }; + let mut exponent: i16 = ((bits >> 52) & 0x7ff) as i16; + let mantissa = if exponent == 0 { + (bits & 0xfffffffffffff) << 1 + } else { + (bits & 0xfffffffffffff) | 0x10000000000000 + }; + // Exponent bias + mantissa shift + exponent -= 1023 + 52; + (mantissa, exponent, sign) + } + /// Archimedes' constant #[inline] fn pi() -> f64 { 3.14159265358979323846264338327950288 } @@ -497,159 +638,16 @@ impl Real for f64 { /// Converts to degrees, assuming the number is in radians #[inline] - fn to_degrees(&self) -> f64 { *self * (180.0f64 / Real::pi()) } + fn to_degrees(&self) -> f64 { *self * (180.0f64 / Float::pi()) } /// Converts to radians, assuming the number is in degrees #[inline] fn to_radians(&self) -> f64 { - let value: f64 = Real::pi(); + let value: f64 = Float::pi(); *self * (value / 180.0) } } -impl Bounded for f64 { - #[inline] - fn min_value() -> f64 { 2.2250738585072014e-308 } - - #[inline] - fn max_value() -> f64 { 1.7976931348623157e+308 } -} - -impl Primitive for f64 {} - -impl Float for f64 { - #[inline] - fn nan() -> f64 { 0.0 / 0.0 } - - #[inline] - fn infinity() -> f64 { 1.0 / 0.0 } - - #[inline] - fn neg_infinity() -> f64 { -1.0 / 0.0 } - - #[inline] - fn neg_zero() -> f64 { -0.0 } - - /// Returns `true` if the number is NaN - #[inline] - fn is_nan(&self) -> bool { *self != *self } - - /// Returns `true` if the number is infinite - #[inline] - fn is_infinite(&self) -> bool { - *self == Float::infinity() || *self == Float::neg_infinity() - } - - /// Returns `true` if the number is neither infinite or NaN - #[inline] - fn is_finite(&self) -> bool { - !(self.is_nan() || self.is_infinite()) - } - - /// Returns `true` if the number is neither zero, infinite, subnormal or NaN - #[inline] - fn is_normal(&self) -> bool { - self.classify() == FPNormal - } - - /// Returns the floating point category of the number. If only one property is going to - /// be tested, it is generally faster to use the specific predicate instead. - fn classify(&self) -> FPCategory { - static EXP_MASK: u64 = 0x7ff0000000000000; - static MAN_MASK: u64 = 0x000fffffffffffff; - - match ( - unsafe { ::cast::transmute::<f64,u64>(*self) } & MAN_MASK, - unsafe { ::cast::transmute::<f64,u64>(*self) } & EXP_MASK, - ) { - (0, 0) => FPZero, - (_, 0) => FPSubnormal, - (0, EXP_MASK) => FPInfinite, - (_, EXP_MASK) => FPNaN, - _ => FPNormal, - } - } - - #[inline] - fn mantissa_digits(_: Option<f64>) -> uint { 53 } - - #[inline] - fn digits(_: Option<f64>) -> uint { 15 } - - #[inline] - fn epsilon() -> f64 { 2.2204460492503131e-16 } - - #[inline] - fn min_exp(_: Option<f64>) -> int { -1021 } - - #[inline] - fn max_exp(_: Option<f64>) -> int { 1024 } - - #[inline] - fn min_10_exp(_: Option<f64>) -> int { -307 } - - #[inline] - fn max_10_exp(_: Option<f64>) -> int { 308 } - - /// Constructs a floating point number by multiplying `x` by 2 raised to the power of `exp` - #[inline] - fn ldexp(x: f64, exp: int) -> f64 { - ldexp(x, exp as c_int) - } - - /// Breaks the number into a normalized fraction and a base-2 exponent, satisfying: - /// - /// - `self = x * pow(2, exp)` - /// - `0.5 <= abs(x) < 1.0` - #[inline] - fn frexp(&self) -> (f64, int) { - let mut exp = 0; - let x = frexp(*self, &mut exp); - (x, exp as int) - } - - /// Returns the exponential of the number, minus `1`, in a way that is accurate - /// even if the number is close to zero - #[inline] - fn exp_m1(&self) -> f64 { exp_m1(*self) } - - /// Returns the natural logarithm of the number plus `1` (`ln(1+n)`) more accurately - /// than if the operations were performed separately - #[inline] - fn ln_1p(&self) -> f64 { ln_1p(*self) } - - /// Fused multiply-add. Computes `(self * a) + b` with only one rounding error. This - /// produces a more accurate result with better performance than a separate multiplication - /// operation followed by an add. - #[inline] - fn mul_add(&self, a: f64, b: f64) -> f64 { - mul_add(*self, a, b) - } - - /// Returns the next representable floating-point value in the direction of `other` - #[inline] - fn next_after(&self, other: f64) -> f64 { - next_after(*self, other) - } - - /// Returns the mantissa, exponent and sign as integers. - fn integer_decode(&self) -> (u64, i16, i8) { - let bits: u64 = unsafe { - ::cast::transmute(*self) - }; - let sign: i8 = if bits >> 63 == 0 { 1 } else { -1 }; - let mut exponent: i16 = ((bits >> 52) & 0x7ff) as i16; - let mantissa = if exponent == 0 { - (bits & 0xfffffffffffff) << 1 - } else { - (bits & 0xfffffffffffff) | 0x10000000000000 - }; - // Exponent bias + mantissa shift - exponent -= 1023 + 52; - (mantissa, exponent, sign) - } -} - // // Section: String Conversions // @@ -999,23 +997,23 @@ mod tests { #[test] fn test_real_consts() { - let pi: f64 = Real::pi(); - let two_pi: f64 = Real::two_pi(); - let frac_pi_2: f64 = Real::frac_pi_2(); - let frac_pi_3: f64 = Real::frac_pi_3(); - let frac_pi_4: f64 = Real::frac_pi_4(); - let frac_pi_6: f64 = Real::frac_pi_6(); - let frac_pi_8: f64 = Real::frac_pi_8(); - let frac_1_pi: f64 = Real::frac_1_pi(); - let frac_2_pi: f64 = Real::frac_2_pi(); - let frac_2_sqrtpi: f64 = Real::frac_2_sqrtpi(); - let sqrt2: f64 = Real::sqrt2(); - let frac_1_sqrt2: f64 = Real::frac_1_sqrt2(); - let e: f64 = Real::e(); - let log2_e: f64 = Real::log2_e(); - let log10_e: f64 = Real::log10_e(); - let ln_2: f64 = Real::ln_2(); - let ln_10: f64 = Real::ln_10(); + let pi: f64 = Float::pi(); + let two_pi: f64 = Float::two_pi(); + let frac_pi_2: f64 = Float::frac_pi_2(); + let frac_pi_3: f64 = Float::frac_pi_3(); + let frac_pi_4: f64 = Float::frac_pi_4(); + let frac_pi_6: f64 = Float::frac_pi_6(); + let frac_pi_8: f64 = Float::frac_pi_8(); + let frac_1_pi: f64 = Float::frac_1_pi(); + let frac_2_pi: f64 = Float::frac_2_pi(); + let frac_2_sqrtpi: f64 = Float::frac_2_sqrtpi(); + let sqrt2: f64 = Float::sqrt2(); + let frac_1_sqrt2: f64 = Float::frac_1_sqrt2(); + let e: f64 = Float::e(); + let log2_e: f64 = Float::log2_e(); + let log10_e: f64 = Float::log10_e(); + let ln_2: f64 = Float::ln_2(); + let ln_10: f64 = Float::ln_10(); assert_approx_eq!(two_pi, 2.0 * pi); assert_approx_eq!(frac_pi_2, pi / 2f64); diff --git a/src/libstd/num/mod.rs b/src/libstd/num/mod.rs index 33690a5fddb..026e7ebbd48 100644 --- a/src/libstd/num/mod.rs +++ b/src/libstd/num/mod.rs @@ -166,115 +166,6 @@ pub trait Round { fn fract(&self) -> Self; } -/// Defines constants and methods common to real numbers -pub trait Real: Signed - + Ord - + Round - + Div<Self,Self> { - // Common Constants - // FIXME (#5527): These should be associated constants - fn pi() -> Self; - fn two_pi() -> Self; - fn frac_pi_2() -> Self; - fn frac_pi_3() -> Self; - fn frac_pi_4() -> Self; - fn frac_pi_6() -> Self; - fn frac_pi_8() -> Self; - fn frac_1_pi() -> Self; - fn frac_2_pi() -> Self; - fn frac_2_sqrtpi() -> Self; - fn sqrt2() -> Self; - fn frac_1_sqrt2() -> Self; - fn e() -> Self; - fn log2_e() -> Self; - fn log10_e() -> Self; - fn ln_2() -> Self; - fn ln_10() -> Self; - - // Fractional functions - - /// Take the reciprocal (inverse) of a number, `1/x`. - fn recip(&self) -> Self; - - // Algebraic functions - /// Raise a number to a power. - fn powf(&self, n: &Self) -> Self; - - /// Take the square root of a number. - fn sqrt(&self) -> Self; - /// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`. - fn rsqrt(&self) -> Self; - /// Take the cubic root of a number. - fn cbrt(&self) -> Self; - /// Calculate the length of the hypotenuse of a right-angle triangle given - /// legs of length `x` and `y`. - fn hypot(&self, other: &Self) -> Self; - - // Trigonometric functions - - /// Computes the sine of a number (in radians). - fn sin(&self) -> Self; - /// Computes the cosine of a number (in radians). - fn cos(&self) -> Self; - /// Computes the tangent of a number (in radians). - fn tan(&self) -> Self; - - /// Computes the arcsine of a number. Return value is in radians in - /// the range [-pi/2, pi/2] or NaN if the number is outside the range - /// [-1, 1]. - fn asin(&self) -> Self; - /// Computes the arccosine of a number. Return value is in radians in - /// the range [0, pi] or NaN if the number is outside the range - /// [-1, 1]. - fn acos(&self) -> Self; - /// Computes the arctangent of a number. Return value is in radians in the - /// range [-pi/2, pi/2]; - fn atan(&self) -> Self; - /// Computes the four quadrant arctangent of a number, `y`, and another - /// number `x`. Return value is in radians in the range [-pi, pi]. - fn atan2(&self, other: &Self) -> Self; - /// Simultaneously computes the sine and cosine of the number, `x`. Returns - /// `(sin(x), cos(x))`. - fn sin_cos(&self) -> (Self, Self); - - // Exponential functions - - /// Returns `e^(self)`, (the exponential function). - fn exp(&self) -> Self; - /// Returns 2 raised to the power of the number, `2^(self)`. - fn exp2(&self) -> Self; - /// Returns the natural logarithm of the number. - fn ln(&self) -> Self; - /// Returns the logarithm of the number with respect to an arbitrary base. - fn log(&self, base: &Self) -> Self; - /// Returns the base 2 logarithm of the number. - fn log2(&self) -> Self; - /// Returns the base 10 logarithm of the number. - fn log10(&self) -> Self; - - // Hyperbolic functions - - /// Hyperbolic sine function. - fn sinh(&self) -> Self; - /// Hyperbolic cosine function. - fn cosh(&self) -> Self; - /// Hyperbolic tangent function. - fn tanh(&self) -> Self; - /// Inverse hyperbolic sine function. - fn asinh(&self) -> Self; - /// Inverse hyperbolic cosine function. - fn acosh(&self) -> Self; - /// Inverse hyperbolic tangent function. - fn atanh(&self) -> Self; - - // Angular conversions - - /// Convert radians to degrees. - fn to_degrees(&self) -> Self; - /// Convert degrees to radians. - fn to_radians(&self) -> Self; -} - /// Raises a value to the power of exp, using exponentiation by squaring. /// /// # Example @@ -300,67 +191,6 @@ pub fn pow<T: One + Mul<T, T>>(mut base: T, mut exp: uint) -> T { } } -/// Raise a number to a power. -/// -/// # Example -/// -/// ```rust -/// use std::num; -/// -/// let sixteen: f64 = num::powf(2.0, 4.0); -/// assert_eq!(sixteen, 16.0); -/// ``` -#[inline(always)] pub fn powf<T: Real>(value: T, n: T) -> T { value.powf(&n) } -/// Take the square root of a number. -#[inline(always)] pub fn sqrt<T: Real>(value: T) -> T { value.sqrt() } -/// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`. -#[inline(always)] pub fn rsqrt<T: Real>(value: T) -> T { value.rsqrt() } -/// Take the cubic root of a number. -#[inline(always)] pub fn cbrt<T: Real>(value: T) -> T { value.cbrt() } -/// Calculate the length of the hypotenuse of a right-angle triangle given legs of length `x` and -/// `y`. -#[inline(always)] pub fn hypot<T: Real>(x: T, y: T) -> T { x.hypot(&y) } -/// Sine function. -#[inline(always)] pub fn sin<T: Real>(value: T) -> T { value.sin() } -/// Cosine function. -#[inline(always)] pub fn cos<T: Real>(value: T) -> T { value.cos() } -/// Tangent function. -#[inline(always)] pub fn tan<T: Real>(value: T) -> T { value.tan() } -/// Compute the arcsine of the number. -#[inline(always)] pub fn asin<T: Real>(value: T) -> T { value.asin() } -/// Compute the arccosine of the number. -#[inline(always)] pub fn acos<T: Real>(value: T) -> T { value.acos() } -/// Compute the arctangent of the number. -#[inline(always)] pub fn atan<T: Real>(value: T) -> T { value.atan() } -/// Compute the arctangent with 2 arguments. -#[inline(always)] pub fn atan2<T: Real>(x: T, y: T) -> T { x.atan2(&y) } -/// Simultaneously computes the sine and cosine of the number. -#[inline(always)] pub fn sin_cos<T: Real>(value: T) -> (T, T) { value.sin_cos() } -/// Returns `e^(value)`, (the exponential function). -#[inline(always)] pub fn exp<T: Real>(value: T) -> T { value.exp() } -/// Returns 2 raised to the power of the number, `2^(value)`. -#[inline(always)] pub fn exp2<T: Real>(value: T) -> T { value.exp2() } -/// Returns the natural logarithm of the number. -#[inline(always)] pub fn ln<T: Real>(value: T) -> T { value.ln() } -/// Returns the logarithm of the number with respect to an arbitrary base. -#[inline(always)] pub fn log<T: Real>(value: T, base: T) -> T { value.log(&base) } -/// Returns the base 2 logarithm of the number. -#[inline(always)] pub fn log2<T: Real>(value: T) -> T { value.log2() } -/// Returns the base 10 logarithm of the number. -#[inline(always)] pub fn log10<T: Real>(value: T) -> T { value.log10() } -/// Hyperbolic sine function. -#[inline(always)] pub fn sinh<T: Real>(value: T) -> T { value.sinh() } -/// Hyperbolic cosine function. -#[inline(always)] pub fn cosh<T: Real>(value: T) -> T { value.cosh() } -/// Hyperbolic tangent function. -#[inline(always)] pub fn tanh<T: Real>(value: T) -> T { value.tanh() } -/// Inverse hyperbolic sine function. -#[inline(always)] pub fn asinh<T: Real>(value: T) -> T { value.asinh() } -/// Inverse hyperbolic cosine function. -#[inline(always)] pub fn acosh<T: Real>(value: T) -> T { value.acosh() } -/// Inverse hyperbolic tangent function. -#[inline(always)] pub fn atanh<T: Real>(value: T) -> T { value.atanh() } - pub trait Bounded { // FIXME (#5527): These should be associated constants fn min_value() -> Self; @@ -492,8 +322,8 @@ pub enum FPCategory { } /// Primitive floating point numbers -pub trait Float: Real - + Signed +pub trait Float: Signed + + Round + Primitive { // FIXME (#5527): These should be associated constants fn nan() -> Self; @@ -525,6 +355,109 @@ pub trait Float: Real fn next_after(&self, other: Self) -> Self; fn integer_decode(&self) -> (u64, i16, i8); + + // Common Mathematical Constants + // FIXME (#5527): These should be associated constants + fn pi() -> Self; + fn two_pi() -> Self; + fn frac_pi_2() -> Self; + fn frac_pi_3() -> Self; + fn frac_pi_4() -> Self; + fn frac_pi_6() -> Self; + fn frac_pi_8() -> Self; + fn frac_1_pi() -> Self; + fn frac_2_pi() -> Self; + fn frac_2_sqrtpi() -> Self; + fn sqrt2() -> Self; + fn frac_1_sqrt2() -> Self; + fn e() -> Self; + fn log2_e() -> Self; + fn log10_e() -> Self; + fn ln_2() -> Self; + fn ln_10() -> Self; + + // Fractional functions + + /// Take the reciprocal (inverse) of a number, `1/x`. + fn recip(&self) -> Self; + + // Algebraic functions + /// Raise a number to a power. + fn powf(&self, n: &Self) -> Self; + + /// Take the square root of a number. + fn sqrt(&self) -> Self; + /// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`. + fn rsqrt(&self) -> Self; + /// Take the cubic root of a number. + fn cbrt(&self) -> Self; + /// Calculate the length of the hypotenuse of a right-angle triangle given + /// legs of length `x` and `y`. + fn hypot(&self, other: &Self) -> Self; + + // Trigonometric functions + + /// Computes the sine of a number (in radians). + fn sin(&self) -> Self; + /// Computes the cosine of a number (in radians). + fn cos(&self) -> Self; + /// Computes the tangent of a number (in radians). + fn tan(&self) -> Self; + + /// Computes the arcsine of a number. Return value is in radians in + /// the range [-pi/2, pi/2] or NaN if the number is outside the range + /// [-1, 1]. + fn asin(&self) -> Self; + /// Computes the arccosine of a number. Return value is in radians in + /// the range [0, pi] or NaN if the number is outside the range + /// [-1, 1]. + fn acos(&self) -> Self; + /// Computes the arctangent of a number. Return value is in radians in the + /// range [-pi/2, pi/2]; + fn atan(&self) -> Self; + /// Computes the four quadrant arctangent of a number, `y`, and another + /// number `x`. Return value is in radians in the range [-pi, pi]. + fn atan2(&self, other: &Self) -> Self; + /// Simultaneously computes the sine and cosine of the number, `x`. Returns + /// `(sin(x), cos(x))`. + fn sin_cos(&self) -> (Self, Self); + + // Exponential functions + + /// Returns `e^(self)`, (the exponential function). + fn exp(&self) -> Self; + /// Returns 2 raised to the power of the number, `2^(self)`. + fn exp2(&self) -> Self; + /// Returns the natural logarithm of the number. + fn ln(&self) -> Self; + /// Returns the logarithm of the number with respect to an arbitrary base. + fn log(&self, base: &Self) -> Self; + /// Returns the base 2 logarithm of the number. + fn log2(&self) -> Self; + /// Returns the base 10 logarithm of the number. + fn log10(&self) -> Self; + + // Hyperbolic functions + + /// Hyperbolic sine function. + fn sinh(&self) -> Self; + /// Hyperbolic cosine function. + fn cosh(&self) -> Self; + /// Hyperbolic tangent function. + fn tanh(&self) -> Self; + /// Inverse hyperbolic sine function. + fn asinh(&self) -> Self; + /// Inverse hyperbolic cosine function. + fn acosh(&self) -> Self; + /// Inverse hyperbolic tangent function. + fn atanh(&self) -> Self; + + // Angular conversions + + /// Convert radians to degrees. + fn to_degrees(&self) -> Self; + /// Convert degrees to radians. + fn to_radians(&self) -> Self; } /// Returns the exponential of the number, minus `1`, `exp(n) - 1`, in a way @@ -539,6 +472,67 @@ pub trait Float: Real /// architectures) than a separate multiplication operation followed by an add. #[inline(always)] pub fn mul_add<T: Float>(a: T, b: T, c: T) -> T { a.mul_add(b, c) } +/// Raise a number to a power. +/// +/// # Example +/// +/// ```rust +/// use std::num; +/// +/// let sixteen: f64 = num::powf(2.0, 4.0); +/// assert_eq!(sixteen, 16.0); +/// ``` +#[inline(always)] pub fn powf<T: Float>(value: T, n: T) -> T { value.powf(&n) } +/// Take the square root of a number. +#[inline(always)] pub fn sqrt<T: Float>(value: T) -> T { value.sqrt() } +/// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`. +#[inline(always)] pub fn rsqrt<T: Float>(value: T) -> T { value.rsqrt() } +/// Take the cubic root of a number. +#[inline(always)] pub fn cbrt<T: Float>(value: T) -> T { value.cbrt() } +/// Calculate the length of the hypotenuse of a right-angle triangle given legs +/// of length `x` and `y`. +#[inline(always)] pub fn hypot<T: Float>(x: T, y: T) -> T { x.hypot(&y) } +/// Sine function. +#[inline(always)] pub fn sin<T: Float>(value: T) -> T { value.sin() } +/// Cosine function. +#[inline(always)] pub fn cos<T: Float>(value: T) -> T { value.cos() } +/// Tangent function. +#[inline(always)] pub fn tan<T: Float>(value: T) -> T { value.tan() } +/// Compute the arcsine of the number. +#[inline(always)] pub fn asin<T: Float>(value: T) -> T { value.asin() } +/// Compute the arccosine of the number. +#[inline(always)] pub fn acos<T: Float>(value: T) -> T { value.acos() } +/// Compute the arctangent of the number. +#[inline(always)] pub fn atan<T: Float>(value: T) -> T { value.atan() } +/// Compute the arctangent with 2 arguments. +#[inline(always)] pub fn atan2<T: Float>(x: T, y: T) -> T { x.atan2(&y) } +/// Simultaneously computes the sine and cosine of the number. +#[inline(always)] pub fn sin_cos<T: Float>(value: T) -> (T, T) { value.sin_cos() } +/// Returns `e^(value)`, (the exponential function). +#[inline(always)] pub fn exp<T: Float>(value: T) -> T { value.exp() } +/// Returns 2 raised to the power of the number, `2^(value)`. +#[inline(always)] pub fn exp2<T: Float>(value: T) -> T { value.exp2() } +/// Returns the natural logarithm of the number. +#[inline(always)] pub fn ln<T: Float>(value: T) -> T { value.ln() } +/// Returns the logarithm of the number with respect to an arbitrary base. +#[inline(always)] pub fn log<T: Float>(value: T, base: T) -> T { value.log(&base) } +/// Returns the base 2 logarithm of the number. +#[inline(always)] pub fn log2<T: Float>(value: T) -> T { value.log2() } +/// Returns the base 10 logarithm of the number. +#[inline(always)] pub fn log10<T: Float>(value: T) -> T { value.log10() } +/// Hyperbolic sine function. +#[inline(always)] pub fn sinh<T: Float>(value: T) -> T { value.sinh() } +/// Hyperbolic cosine function. +#[inline(always)] pub fn cosh<T: Float>(value: T) -> T { value.cosh() } +/// Hyperbolic tangent function. +#[inline(always)] pub fn tanh<T: Float>(value: T) -> T { value.tanh() } +/// Inverse hyperbolic sine function. +#[inline(always)] pub fn asinh<T: Float>(value: T) -> T { value.asinh() } +/// Inverse hyperbolic cosine function. +#[inline(always)] pub fn acosh<T: Float>(value: T) -> T { value.acosh() } +/// Inverse hyperbolic tangent function. +#[inline(always)] pub fn atanh<T: Float>(value: T) -> T { value.atanh() } + /// A generic trait for converting a value to a number. pub trait ToPrimitive { /// Converts the value of `self` to an `int`. diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index bd21bb4e754..e2b62725043 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -58,7 +58,7 @@ pub use hash::Hash; pub use iter::{FromIterator, Extendable}; pub use iter::{Iterator, DoubleEndedIterator, RandomAccessIterator, CloneableIterator}; pub use iter::{OrdIterator, MutableDoubleEndedIterator, ExactSize}; -pub use num::{Integer, Real, Num, NumCast, CheckedAdd, CheckedSub, CheckedMul}; +pub use num::{Integer, Num, NumCast, CheckedAdd, CheckedSub, CheckedMul}; pub use num::{Signed, Unsigned, Round}; pub use num::{Primitive, Int, Float, ToStrRadix, ToPrimitive, FromPrimitive}; pub use path::{GenericPath, Path, PosixPath, WindowsPath}; diff --git a/src/libstd/rand/distributions/exponential.rs b/src/libstd/rand/distributions/exponential.rs index 287a4a36293..09c36d945eb 100644 --- a/src/libstd/rand/distributions/exponential.rs +++ b/src/libstd/rand/distributions/exponential.rs @@ -10,7 +10,7 @@ //! The exponential distribution. -use num::Real; +use num::Float; use rand::{Rng, Rand}; use rand::distributions::{ziggurat, ziggurat_tables, Sample, IndependentSample}; diff --git a/src/libstd/rand/distributions/gamma.rs b/src/libstd/rand/distributions/gamma.rs index 0915d49945d..a14b58188bd 100644 --- a/src/libstd/rand/distributions/gamma.rs +++ b/src/libstd/rand/distributions/gamma.rs @@ -10,7 +10,7 @@ //! The Gamma and derived distributions. -use num::Real; +use num::Float; use num; use rand::{Rng, Open01}; use super::normal::StandardNormal; diff --git a/src/libstd/rand/distributions/normal.rs b/src/libstd/rand/distributions/normal.rs index 074a181ca3c..c9dc3c8abc1 100644 --- a/src/libstd/rand/distributions/normal.rs +++ b/src/libstd/rand/distributions/normal.rs @@ -10,7 +10,7 @@ //! The normal and derived distributions. -use num::Real; +use num::Float; use rand::{Rng, Rand, Open01}; use rand::distributions::{ziggurat, ziggurat_tables, Sample, IndependentSample}; |
