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).
This commit is contained in:
bors 2014-02-17 22:16:51 -08:00
commit b0ce960609
9 changed files with 501 additions and 511 deletions

View File

@ -85,7 +85,7 @@ syn keyword rustTrait Iterator DoubleEndedIterator RandomAccessIterator Cloneabl
syn keyword rustTrait OrdIterator MutableDoubleEndedIterator ExactSize
syn keyword rustTrait Algebraic Trigonometric Exponential Hyperbolic
syn keyword rustTrait Bitwise Bounded Integer Fractional Real RealExt
syn keyword rustTrait Bitwise Bounded Integer
syn keyword rustTrait Num NumCast CheckedAdd CheckedSub CheckedMul CheckedDiv
syn keyword rustTrait Orderable Signed Unsigned Round
syn keyword rustTrait Primitive Int Float ToStrRadix ToPrimitive FromPrimitive

View File

@ -77,7 +77,7 @@ impl<T: Clone + Num> Cmplx<T> {
}
}
impl<T: Clone + Real> Cmplx<T> {
impl<T: Clone + Float> Cmplx<T> {
/// Calculate |self|
#[inline]
pub fn norm(&self) -> T {
@ -85,7 +85,7 @@ impl<T: Clone + Real> Cmplx<T> {
}
}
impl<T: Clone + Real> Cmplx<T> {
impl<T: Clone + Float> Cmplx<T> {
/// Calculate the principal Arg of self.
#[inline]
pub fn arg(&self) -> T {
@ -192,7 +192,7 @@ mod test {
#[allow(non_uppercase_statics)];
use super::{Complex64, Cmplx};
use std::num::{Zero,One,Real};
use std::num::{Zero,One,Float};
pub static _0_0i : Complex64 = Cmplx { re: 0.0, im: 0.0 };
pub static _1_0i : Complex64 = Cmplx { re: 1.0, im: 0.0 };
@ -270,9 +270,9 @@ mod test {
assert!((c.arg() - arg).abs() < 1.0e-6)
}
test(_1_0i, 0.0);
test(_1_1i, 0.25 * Real::pi());
test(_neg1_1i, 0.75 * Real::pi());
test(_05_05i, 0.25 * Real::pi());
test(_1_1i, 0.25 * Float::pi());
test(_neg1_1i, 0.75 * Float::pi());
test(_05_05i, 0.25 * Float::pi());
}
#[test]

View File

@ -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);

View File

@ -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);

View File

@ -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`.

View File

@ -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};

View File

@ -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};

View File

@ -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;

View File

@ -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};