]> git.lizzy.rs Git - rust.git/commitdiff
core: Move intrinsic float functionality from std
authorAlex Crichton <alex@alexcrichton.com>
Sat, 10 May 2014 20:25:49 +0000 (13:25 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Fri, 16 May 2014 06:22:06 +0000 (23:22 -0700)
The Float trait in libstd is quite a large trait which has dependencies on cmath
(libm) and such, which libcore cannot satisfy. It also has many functions that
libcore can implement, however, as LLVM has intrinsics or they're just bit
twiddling.

This commit moves what it can of the Float trait from the standard library into
libcore to allow floats to be usable in the core library. The remaining
functions are now resident in a FloatMath trait in the standard library (in the
prelude now). Previous code which was generic over just the Float trait may now
need to be generic over the FloatMath trait.

[breaking-change]

src/libcore/num/f32.rs
src/libcore/num/f64.rs
src/libcore/num/mod.rs
src/libnum/complex.rs
src/libstd/num/f32.rs
src/libstd/num/f64.rs
src/libstd/num/mod.rs
src/libtest/stats.rs

index c4cdc5a0a4017e90d3ce7af9d2c18b99b11cdbbe..694f3e9fbd1f90ee2292975927d140421c4009a3 100644 (file)
 
 use default::Default;
 use intrinsics;
-use num::{Zero, One, Bounded, Signed, Num, Primitive};
+use mem;
+use num::{FPNormal, FPCategory, FPZero, FPSubnormal, FPInfinite, FPNaN};
+use num::{Zero, One, Bounded, Signed, Num, Primitive, Float};
+use option::Option;
 
 #[cfg(not(test))] use cmp::{Eq, Ord};
 #[cfg(not(test))] use ops::{Add, Sub, Mul, Div, Rem, Neg};
@@ -225,3 +228,270 @@ fn min_value() -> f32 { -MAX_VALUE }
     #[inline]
     fn max_value() -> f32 { MAX_VALUE }
 }
+
+impl Float for f32 {
+    #[inline]
+    fn nan() -> f32 { NAN }
+
+    #[inline]
+    fn infinity() -> f32 { INFINITY }
+
+    #[inline]
+    fn neg_infinity() -> f32 { NEG_INFINITY }
+
+    #[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;
+
+        let bits: u32 = unsafe { mem::transmute(self) };
+        match (bits & MAN_MASK, bits & EXP_MASK) {
+            (0, 0)        => FPZero,
+            (_, 0)        => FPSubnormal,
+            (0, EXP_MASK) => FPInfinite,
+            (_, EXP_MASK) => FPNaN,
+            _             => FPNormal,
+        }
+    }
+
+    #[inline]
+    fn mantissa_digits(_: Option<f32>) -> uint { MANTISSA_DIGITS }
+
+    #[inline]
+    fn digits(_: Option<f32>) -> uint { DIGITS }
+
+    #[inline]
+    fn epsilon() -> f32 { EPSILON }
+
+    #[inline]
+    fn min_exp(_: Option<f32>) -> int { MIN_EXP }
+
+    #[inline]
+    fn max_exp(_: Option<f32>) -> int { MAX_EXP }
+
+    #[inline]
+    fn min_10_exp(_: Option<f32>) -> int { MIN_10_EXP }
+
+    #[inline]
+    fn max_10_exp(_: Option<f32>) -> int { MAX_10_EXP }
+
+    #[inline]
+    fn min_pos_value(_: Option<f32>) -> f32 { MIN_POS_VALUE }
+
+    /// Returns the mantissa, exponent and sign as integers.
+    fn integer_decode(self) -> (u64, i16, i8) {
+        let bits: u32 = unsafe { mem::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)
+    }
+
+    /// Round half-way cases toward `NEG_INFINITY`
+    #[inline]
+    fn floor(self) -> f32 {
+        unsafe { intrinsics::floorf32(self) }
+    }
+
+    /// Round half-way cases toward `INFINITY`
+    #[inline]
+    fn ceil(self) -> f32 {
+        unsafe { intrinsics::ceilf32(self) }
+    }
+
+    /// Round half-way cases away from `0.0`
+    #[inline]
+    fn round(self) -> f32 {
+        unsafe { intrinsics::roundf32(self) }
+    }
+
+    /// The integer part of the number (rounds towards `0.0`)
+    #[inline]
+    fn trunc(self) -> f32 {
+        unsafe { intrinsics::truncf32(self) }
+    }
+
+    /// The fractional part of the number, satisfying:
+    ///
+    /// ```rust
+    /// let x = 1.65f32;
+    /// assert!(x == x.trunc() + x.fract())
+    /// ```
+    #[inline]
+    fn fract(self) -> f32 { self - self.trunc() }
+
+    /// 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 {
+        unsafe { intrinsics::fmaf32(self, a, b) }
+    }
+
+    /// The reciprocal (multiplicative inverse) of the number
+    #[inline]
+    fn recip(self) -> f32 { 1.0 / self }
+
+    fn powi(self, n: i32) -> f32 {
+        unsafe { intrinsics::powif32(self, n) }
+    }
+
+    #[inline]
+    fn powf(self, n: f32) -> f32 {
+        unsafe { intrinsics::powf32(self, n) }
+    }
+
+    /// sqrt(2.0)
+    #[inline]
+    fn sqrt2() -> f32 { consts::SQRT2 }
+
+    /// 1.0 / sqrt(2.0)
+    #[inline]
+    fn frac_1_sqrt2() -> f32 { consts::FRAC_1_SQRT2 }
+
+    #[inline]
+    fn sqrt(self) -> f32 {
+        unsafe { intrinsics::sqrtf32(self) }
+    }
+
+    #[inline]
+    fn rsqrt(self) -> f32 { self.sqrt().recip() }
+
+    /// Archimedes' constant
+    #[inline]
+    fn pi() -> f32 { consts::PI }
+
+    /// 2.0 * pi
+    #[inline]
+    fn two_pi() -> f32 { consts::PI_2 }
+
+    /// pi / 2.0
+    #[inline]
+    fn frac_pi_2() -> f32 { consts::FRAC_PI_2 }
+
+    /// pi / 3.0
+    #[inline]
+    fn frac_pi_3() -> f32 { consts::FRAC_PI_3 }
+
+    /// pi / 4.0
+    #[inline]
+    fn frac_pi_4() -> f32 { consts::FRAC_PI_4 }
+
+    /// pi / 6.0
+    #[inline]
+    fn frac_pi_6() -> f32 { consts::FRAC_PI_6 }
+
+    /// pi / 8.0
+    #[inline]
+    fn frac_pi_8() -> f32 { consts::FRAC_PI_8 }
+
+    /// 1 .0/ pi
+    #[inline]
+    fn frac_1_pi() -> f32 { consts::FRAC_1_PI }
+
+    /// 2.0 / pi
+    #[inline]
+    fn frac_2_pi() -> f32 { consts::FRAC_2_PI }
+
+    /// 2.0 / sqrt(pi)
+    #[inline]
+    fn frac_2_sqrtpi() -> f32 { consts::FRAC_2_SQRTPI }
+
+    /// Euler's number
+    #[inline]
+    fn e() -> f32 { consts::E }
+
+    /// log2(e)
+    #[inline]
+    fn log2_e() -> f32 { consts::LOG2_E }
+
+    /// log10(e)
+    #[inline]
+    fn log10_e() -> f32 { consts::LOG10_E }
+
+    /// ln(2.0)
+    #[inline]
+    fn ln_2() -> f32 { consts::LN_2 }
+
+    /// ln(10.0)
+    #[inline]
+    fn ln_10() -> f32 { consts::LN_10 }
+
+    /// Returns the exponential of the number
+    #[inline]
+    fn exp(self) -> f32 {
+        unsafe { intrinsics::expf32(self) }
+    }
+
+    /// Returns 2 raised to the power of the number
+    #[inline]
+    fn exp2(self) -> f32 {
+        unsafe { intrinsics::exp2f32(self) }
+    }
+
+    /// Returns the natural logarithm of the number
+    #[inline]
+    fn ln(self) -> f32 {
+        unsafe { intrinsics::logf32(self) }
+    }
+
+    /// Returns the logarithm of the number with respect to an arbitrary base
+    #[inline]
+    fn log(self, base: f32) -> f32 { self.ln() / base.ln() }
+
+    /// Returns the base 2 logarithm of the number
+    #[inline]
+    fn log2(self) -> f32 {
+        unsafe { intrinsics::log2f32(self) }
+    }
+
+    /// Returns the base 10 logarithm of the number
+    #[inline]
+    fn log10(self) -> f32 {
+        unsafe { intrinsics::log10f32(self) }
+    }
+
+    /// Converts to degrees, assuming the number is in radians
+    #[inline]
+    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 = Float::pi();
+        self * (value / 180.0f32)
+    }
+}
index b15b4566cdd689e9f1648fa0d96d7550d22d0137..2c802f5d059f1f3dcb7226321f0142a887b16396 100644 (file)
 
 use default::Default;
 use intrinsics;
-use num::{Zero, One, Bounded, Signed, Num, Primitive};
+use mem;
+use num::{FPNormal, FPCategory, FPZero, FPSubnormal, FPInfinite, FPNaN};
+use num::{Zero, One, Bounded, Signed, Num, Primitive, Float};
+use option::Option;
 
 #[cfg(not(test))] use cmp::{Eq, Ord};
 #[cfg(not(test))] use ops::{Add, Sub, Mul, Div, Rem, Neg};
@@ -225,3 +228,273 @@ fn min_value() -> f64 { -MAX_VALUE }
     #[inline]
     fn max_value() -> f64 { MAX_VALUE }
 }
+
+impl Float for f64 {
+    #[inline]
+    fn nan() -> f64 { NAN }
+
+    #[inline]
+    fn infinity() -> f64 { INFINITY }
+
+    #[inline]
+    fn neg_infinity() -> f64 { NEG_INFINITY }
+
+    #[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;
+
+        let bits: u64 = unsafe { mem::transmute(self) };
+        match (bits & MAN_MASK, bits & EXP_MASK) {
+            (0, 0)        => FPZero,
+            (_, 0)        => FPSubnormal,
+            (0, EXP_MASK) => FPInfinite,
+            (_, EXP_MASK) => FPNaN,
+            _             => FPNormal,
+        }
+    }
+
+    #[inline]
+    fn mantissa_digits(_: Option<f64>) -> uint { MANTISSA_DIGITS }
+
+    #[inline]
+    fn digits(_: Option<f64>) -> uint { DIGITS }
+
+    #[inline]
+    fn epsilon() -> f64 { EPSILON }
+
+    #[inline]
+    fn min_exp(_: Option<f64>) -> int { MIN_EXP }
+
+    #[inline]
+    fn max_exp(_: Option<f64>) -> int { MAX_EXP }
+
+    #[inline]
+    fn min_10_exp(_: Option<f64>) -> int { MIN_10_EXP }
+
+    #[inline]
+    fn max_10_exp(_: Option<f64>) -> int { MAX_10_EXP }
+
+    #[inline]
+    fn min_pos_value(_: Option<f64>) -> f64 { MIN_POS_VALUE }
+
+    /// Returns the mantissa, exponent and sign as integers.
+    fn integer_decode(self) -> (u64, i16, i8) {
+        let bits: u64 = unsafe { mem::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)
+    }
+
+    /// Round half-way cases toward `NEG_INFINITY`
+    #[inline]
+    fn floor(self) -> f64 {
+        unsafe { intrinsics::floorf64(self) }
+    }
+
+    /// Round half-way cases toward `INFINITY`
+    #[inline]
+    fn ceil(self) -> f64 {
+        unsafe { intrinsics::ceilf64(self) }
+    }
+
+    /// Round half-way cases away from `0.0`
+    #[inline]
+    fn round(self) -> f64 {
+        unsafe { intrinsics::roundf64(self) }
+    }
+
+    /// The integer part of the number (rounds towards `0.0`)
+    #[inline]
+    fn trunc(self) -> f64 {
+        unsafe { intrinsics::truncf64(self) }
+    }
+
+    /// The fractional part of the number, satisfying:
+    ///
+    /// ```rust
+    /// let x = 1.65f64;
+    /// assert!(x == x.trunc() + x.fract())
+    /// ```
+    #[inline]
+    fn fract(self) -> f64 { self - self.trunc() }
+
+    /// 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 {
+        unsafe { intrinsics::fmaf64(self, a, b) }
+    }
+
+    /// The reciprocal (multiplicative inverse) of the number
+    #[inline]
+    fn recip(self) -> f64 { 1.0 / self }
+
+    #[inline]
+    fn powf(self, n: f64) -> f64 {
+        unsafe { intrinsics::powf64(self, n) }
+    }
+
+    #[inline]
+    fn powi(self, n: i32) -> f64 {
+        unsafe { intrinsics::powif64(self, n) }
+    }
+
+    /// sqrt(2.0)
+    #[inline]
+    fn sqrt2() -> f64 { consts::SQRT2 }
+
+    /// 1.0 / sqrt(2.0)
+    #[inline]
+    fn frac_1_sqrt2() -> f64 { consts::FRAC_1_SQRT2 }
+
+    #[inline]
+    fn sqrt(self) -> f64 {
+        unsafe { intrinsics::sqrtf64(self) }
+    }
+
+    #[inline]
+    fn rsqrt(self) -> f64 { self.sqrt().recip() }
+
+    /// Archimedes' constant
+    #[inline]
+    fn pi() -> f64 { consts::PI }
+
+    /// 2.0 * pi
+    #[inline]
+    fn two_pi() -> f64 { consts::PI_2 }
+
+    /// pi / 2.0
+    #[inline]
+    fn frac_pi_2() -> f64 { consts::FRAC_PI_2 }
+
+    /// pi / 3.0
+    #[inline]
+    fn frac_pi_3() -> f64 { consts::FRAC_PI_3 }
+
+    /// pi / 4.0
+    #[inline]
+    fn frac_pi_4() -> f64 { consts::FRAC_PI_4 }
+
+    /// pi / 6.0
+    #[inline]
+    fn frac_pi_6() -> f64 { consts::FRAC_PI_6 }
+
+    /// pi / 8.0
+    #[inline]
+    fn frac_pi_8() -> f64 { consts::FRAC_PI_8 }
+
+    /// 1.0 / pi
+    #[inline]
+    fn frac_1_pi() -> f64 { consts::FRAC_1_PI }
+
+    /// 2.0 / pi
+    #[inline]
+    fn frac_2_pi() -> f64 { consts::FRAC_2_PI }
+
+    /// 2.0 / sqrt(pi)
+    #[inline]
+    fn frac_2_sqrtpi() -> f64 { consts::FRAC_2_SQRTPI }
+
+    /// Euler's number
+    #[inline]
+    fn e() -> f64 { consts::E }
+
+    /// log2(e)
+    #[inline]
+    fn log2_e() -> f64 { consts::LOG2_E }
+
+    /// log10(e)
+    #[inline]
+    fn log10_e() -> f64 { consts::LOG10_E }
+
+    /// ln(2.0)
+    #[inline]
+    fn ln_2() -> f64 { consts::LN_2 }
+
+    /// ln(10.0)
+    #[inline]
+    fn ln_10() -> f64 { consts::LN_10 }
+
+    /// Returns the exponential of the number
+    #[inline]
+    fn exp(self) -> f64 {
+        unsafe { intrinsics::expf64(self) }
+    }
+
+    /// Returns 2 raised to the power of the number
+    #[inline]
+    fn exp2(self) -> f64 {
+        unsafe { intrinsics::exp2f64(self) }
+    }
+
+    /// Returns the natural logarithm of the number
+    #[inline]
+    fn ln(self) -> f64 {
+        unsafe { intrinsics::logf64(self) }
+    }
+
+    /// Returns the logarithm of the number with respect to an arbitrary base
+    #[inline]
+    fn log(self, base: f64) -> f64 { self.ln() / base.ln() }
+
+    /// Returns the base 2 logarithm of the number
+    #[inline]
+    fn log2(self) -> f64 {
+        unsafe { intrinsics::log2f64(self) }
+    }
+
+    /// Returns the base 10 logarithm of the number
+    #[inline]
+    fn log10(self) -> f64 {
+        unsafe { intrinsics::log10f64(self) }
+    }
+
+
+    /// Converts to degrees, assuming the number is in radians
+    #[inline]
+    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 = Float::pi();
+        self * (value / 180.0)
+    }
+}
+
index 22411fef3b26801884c5a5d94ae81274c08c9dac..47be5df67eabdb345c963e9cc58ccd9dfcaf8c39 100644 (file)
@@ -874,3 +874,157 @@ pub fn test_num<T:Num + NumCast + ::std::fmt::Show>(ten: T, two: T) {
     assert_eq!(ten.div(&two),  ten / two);
     assert_eq!(ten.rem(&two),  ten % two);
 }
+
+/// Used for representing the classification of floating point numbers
+#[deriving(Eq, Show)]
+pub enum FPCategory {
+    /// "Not a Number", often obtained by dividing by zero
+    FPNaN,
+    /// Positive or negative infinity
+    FPInfinite ,
+    /// Positive or negative zero
+    FPZero,
+    /// De-normalized floating point representation (less precise than `FPNormal`)
+    FPSubnormal,
+    /// A regular floating point number
+    FPNormal,
+}
+
+/// Operations on primitive floating point numbers.
+// FIXME(#5527): In a future version of Rust, many of these functions will
+//               become constants.
+//
+// FIXME(#8888): Several of these functions have a parameter named
+//               `unused_self`. Removing it requires #8888 to be fixed.
+pub trait Float: Signed + Primitive {
+    /// Returns the NaN value.
+    fn nan() -> Self;
+    /// Returns the infinite value.
+    fn infinity() -> Self;
+    /// Returns the negative infinite value.
+    fn neg_infinity() -> Self;
+    /// Returns -0.0.
+    fn neg_zero() -> Self;
+
+    /// Returns true if this value is NaN and false otherwise.
+    fn is_nan(self) -> bool;
+    /// Returns true if this value is positive infinity or negative infinity and
+    /// false otherwise.
+    fn is_infinite(self) -> bool;
+    /// Returns true if this number is neither infinite nor NaN.
+    fn is_finite(self) -> bool;
+    /// Returns true if this number is neither zero, infinite, denormal, or NaN.
+    fn is_normal(self) -> bool;
+    /// Returns the category that this number falls into.
+    fn classify(self) -> FPCategory;
+
+    // FIXME (#5527): These should be associated constants
+
+    /// Returns the number of binary digits of mantissa that this type supports.
+    fn mantissa_digits(unused_self: Option<Self>) -> uint;
+    /// Returns the number of base-10 digits of precision that this type supports.
+    fn digits(unused_self: Option<Self>) -> uint;
+    /// Returns the difference between 1.0 and the smallest representable number larger than 1.0.
+    fn epsilon() -> Self;
+    /// Returns the minimum binary exponent that this type can represent.
+    fn min_exp(unused_self: Option<Self>) -> int;
+    /// Returns the maximum binary exponent that this type can represent.
+    fn max_exp(unused_self: Option<Self>) -> int;
+    /// Returns the minimum base-10 exponent that this type can represent.
+    fn min_10_exp(unused_self: Option<Self>) -> int;
+    /// Returns the maximum base-10 exponent that this type can represent.
+    fn max_10_exp(unused_self: Option<Self>) -> int;
+    /// Returns the smallest normalized positive number that this type can represent.
+    fn min_pos_value(unused_self: Option<Self>) -> Self;
+
+    /// Returns the mantissa, exponent and sign as integers, respectively.
+    fn integer_decode(self) -> (u64, i16, i8);
+
+    /// Return the largest integer less than or equal to a number.
+    fn floor(self) -> Self;
+    /// Return the smallest integer greater than or equal to a number.
+    fn ceil(self) -> Self;
+    /// Return the nearest integer to a number. Round half-way cases away from
+    /// `0.0`.
+    fn round(self) -> Self;
+    /// Return the integer part of a number.
+    fn trunc(self) -> Self;
+    /// Return the fractional part of a number.
+    fn fract(self) -> 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.
+    fn mul_add(self, a: Self, b: Self) -> Self;
+    /// Take the reciprocal (inverse) of a number, `1/x`.
+    fn recip(self) -> Self;
+
+    /// Raise a number to an integer power.
+    ///
+    /// Using this function is generally faster than using `powf`
+    fn powi(self, n: i32) -> Self;
+    /// Raise a number to a floating point power.
+    fn powf(self, n: Self) -> Self;
+
+    /// sqrt(2.0).
+    fn sqrt2() -> Self;
+    /// 1.0 / sqrt(2.0).
+    fn frac_1_sqrt2() -> 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;
+
+    // FIXME (#5527): These should be associated constants
+
+    /// Archimedes' constant.
+    fn pi() -> Self;
+    /// 2.0 * pi.
+    fn two_pi() -> Self;
+    /// pi / 2.0.
+    fn frac_pi_2() -> Self;
+    /// pi / 3.0.
+    fn frac_pi_3() -> Self;
+    /// pi / 4.0.
+    fn frac_pi_4() -> Self;
+    /// pi / 6.0.
+    fn frac_pi_6() -> Self;
+    /// pi / 8.0.
+    fn frac_pi_8() -> Self;
+    /// 1.0 / pi.
+    fn frac_1_pi() -> Self;
+    /// 2.0 / pi.
+    fn frac_2_pi() -> Self;
+    /// 2.0 / sqrt(pi).
+    fn frac_2_sqrtpi() -> Self;
+
+    /// Euler's number.
+    fn e() -> Self;
+    /// log2(e).
+    fn log2_e() -> Self;
+    /// log10(e).
+    fn log10_e() -> Self;
+    /// ln(2.0).
+    fn ln_2() -> Self;
+    /// ln(10.0).
+    fn ln_10() -> Self;
+
+    /// 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;
+
+    /// Convert radians to degrees.
+    fn to_degrees(self) -> Self;
+    /// Convert degrees to radians.
+    fn to_radians(self) -> Self;
+}
index b82c4d177ba02e18a4dce036930f0f77b812ec75..2fc46628616fc289e611929418296385369ba6fe 100644 (file)
@@ -78,7 +78,7 @@ pub fn inv(&self) -> Complex<T> {
     }
 }
 
-impl<T: Clone + Float> Complex<T> {
+impl<T: Clone + FloatMath> Complex<T> {
     /// Calculate |self|
     #[inline]
     pub fn norm(&self) -> T {
@@ -86,7 +86,7 @@ pub fn norm(&self) -> T {
     }
 }
 
-impl<T: Clone + Float> Complex<T> {
+impl<T: Clone + FloatMath> Complex<T> {
     /// Calculate the principal Arg of self.
     #[inline]
     pub fn arg(&self) -> T {
index 29c206b32fc36a89617360bfbadda42993166071..cf02d5b0d5f0ad953b859ffa31f6123a4c761d56 100644 (file)
@@ -18,7 +18,6 @@
 use from_str::FromStr;
 use intrinsics;
 use libc::c_int;
-use mem;
 use num::strconv;
 use num::{FPCategory, FPNaN, FPInfinite , FPZero, FPSubnormal, FPNormal};
 use num;
@@ -69,82 +68,7 @@ mod cmath {
     }
 }
 
-impl Float for f32 {
-    #[inline]
-    fn nan() -> f32 { NAN }
-
-    #[inline]
-    fn infinity() -> f32 { INFINITY }
-
-    #[inline]
-    fn neg_infinity() -> f32 { NEG_INFINITY }
-
-    #[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;
-
-        let bits: u32 = unsafe { mem::transmute(self) };
-        match (bits & MAN_MASK, bits & EXP_MASK) {
-            (0, 0)        => FPZero,
-            (_, 0)        => FPSubnormal,
-            (0, EXP_MASK) => FPInfinite,
-            (_, EXP_MASK) => FPNaN,
-            _             => FPNormal,
-        }
-    }
-
-    #[inline]
-    fn mantissa_digits(_: Option<f32>) -> uint { MANTISSA_DIGITS }
-
-    #[inline]
-    fn digits(_: Option<f32>) -> uint { DIGITS }
-
-    #[inline]
-    fn epsilon() -> f32 { EPSILON }
-
-    #[inline]
-    fn min_exp(_: Option<f32>) -> int { MIN_EXP }
-
-    #[inline]
-    fn max_exp(_: Option<f32>) -> int { MAX_EXP }
-
-    #[inline]
-    fn min_10_exp(_: Option<f32>) -> int { MIN_10_EXP }
-
-    #[inline]
-    fn max_10_exp(_: Option<f32>) -> int { MAX_10_EXP }
-
-    #[inline]
-    fn min_pos_value(_: Option<f32>) -> f32 { MIN_POS_VALUE }
-
+impl FloatMath for f32 {
     /// Constructs a floating point number by multiplying `x` by 2 raised to the
     /// power of `exp`
     #[inline]
@@ -166,21 +90,6 @@ fn frexp(self) -> (f32, int) {
         }
     }
 
-    /// Returns the mantissa, exponent and sign as integers.
-    fn integer_decode(self) -> (u64, i16, i8) {
-        let bits: u32 = unsafe { mem::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)
-    }
-
     /// Returns the next representable floating-point value in the direction of
     /// `other`.
     #[inline]
@@ -188,39 +97,6 @@ fn next_after(self, other: f32) -> f32 {
         unsafe { cmath::nextafterf(self, other) }
     }
 
-    /// Round half-way cases toward `NEG_INFINITY`
-    #[inline]
-    fn floor(self) -> f32 {
-        unsafe { intrinsics::floorf32(self) }
-    }
-
-    /// Round half-way cases toward `INFINITY`
-    #[inline]
-    fn ceil(self) -> f32 {
-        unsafe { intrinsics::ceilf32(self) }
-    }
-
-    /// Round half-way cases away from `0.0`
-    #[inline]
-    fn round(self) -> f32 {
-        unsafe { intrinsics::roundf32(self) }
-    }
-
-    /// The integer part of the number (rounds towards `0.0`)
-    #[inline]
-    fn trunc(self) -> f32 {
-        unsafe { intrinsics::truncf32(self) }
-    }
-
-    /// The fractional part of the number, satisfying:
-    ///
-    /// ```rust
-    /// let x = 1.65f32;
-    /// assert!(x == x.trunc() + x.fract())
-    /// ```
-    #[inline]
-    fn fract(self) -> f32 { self - self.trunc() }
-
     #[inline]
     fn max(self, other: f32) -> f32 {
         unsafe { cmath::fmaxf(self, other) }
@@ -231,43 +107,6 @@ fn min(self, other: f32) -> f32 {
         unsafe { cmath::fminf(self, other) }
     }
 
-    /// 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 {
-        unsafe { intrinsics::fmaf32(self, a, b) }
-    }
-
-    /// The reciprocal (multiplicative inverse) of the number
-    #[inline]
-    fn recip(self) -> f32 { 1.0 / self }
-
-    fn powi(self, n: i32) -> f32 {
-        unsafe { intrinsics::powif32(self, n) }
-    }
-
-    #[inline]
-    fn powf(self, n: f32) -> f32 {
-        unsafe { intrinsics::powf32(self, n) }
-    }
-
-    /// sqrt(2.0)
-    #[inline]
-    fn sqrt2() -> f32 { consts::SQRT2 }
-
-    /// 1.0 / sqrt(2.0)
-    #[inline]
-    fn frac_1_sqrt2() -> f32 { consts::FRAC_1_SQRT2 }
-
-    #[inline]
-    fn sqrt(self) -> f32 {
-        unsafe { intrinsics::sqrtf32(self) }
-    }
-
-    #[inline]
-    fn rsqrt(self) -> f32 { self.sqrt().recip() }
-
     #[inline]
     fn cbrt(self) -> f32 {
         unsafe { cmath::cbrtf(self) }
@@ -278,46 +117,6 @@ fn hypot(self, other: f32) -> f32 {
         unsafe { cmath::hypotf(self, other) }
     }
 
-    /// Archimedes' constant
-    #[inline]
-    fn pi() -> f32 { consts::PI }
-
-    /// 2.0 * pi
-    #[inline]
-    fn two_pi() -> f32 { consts::PI_2 }
-
-    /// pi / 2.0
-    #[inline]
-    fn frac_pi_2() -> f32 { consts::FRAC_PI_2 }
-
-    /// pi / 3.0
-    #[inline]
-    fn frac_pi_3() -> f32 { consts::FRAC_PI_3 }
-
-    /// pi / 4.0
-    #[inline]
-    fn frac_pi_4() -> f32 { consts::FRAC_PI_4 }
-
-    /// pi / 6.0
-    #[inline]
-    fn frac_pi_6() -> f32 { consts::FRAC_PI_6 }
-
-    /// pi / 8.0
-    #[inline]
-    fn frac_pi_8() -> f32 { consts::FRAC_PI_8 }
-
-    /// 1 .0/ pi
-    #[inline]
-    fn frac_1_pi() -> f32 { consts::FRAC_1_PI }
-
-    /// 2.0 / pi
-    #[inline]
-    fn frac_2_pi() -> f32 { consts::FRAC_2_PI }
-
-    /// 2.0 / sqrt(pi)
-    #[inline]
-    fn frac_2_sqrtpi() -> f32 { consts::FRAC_2_SQRTPI }
-
     #[inline]
     fn sin(self) -> f32 {
         unsafe { intrinsics::sinf32(self) }
@@ -359,38 +158,6 @@ fn sin_cos(self) -> (f32, f32) {
         (self.sin(), self.cos())
     }
 
-    /// Euler's number
-    #[inline]
-    fn e() -> f32 { consts::E }
-
-    /// log2(e)
-    #[inline]
-    fn log2_e() -> f32 { consts::LOG2_E }
-
-    /// log10(e)
-    #[inline]
-    fn log10_e() -> f32 { consts::LOG10_E }
-
-    /// ln(2.0)
-    #[inline]
-    fn ln_2() -> f32 { consts::LN_2 }
-
-    /// ln(10.0)
-    #[inline]
-    fn ln_10() -> f32 { consts::LN_10 }
-
-    /// Returns the exponential of the number
-    #[inline]
-    fn exp(self) -> f32 {
-        unsafe { intrinsics::expf32(self) }
-    }
-
-    /// Returns 2 raised to the power of the number
-    #[inline]
-    fn exp2(self) -> f32 {
-        unsafe { intrinsics::exp2f32(self) }
-    }
-
     /// Returns the exponential of the number, minus `1`, in a way that is
     /// accurate even if the number is close to zero
     #[inline]
@@ -398,28 +165,6 @@ fn exp_m1(self) -> f32 {
         unsafe { cmath::expm1f(self) }
     }
 
-    /// Returns the natural logarithm of the number
-    #[inline]
-    fn ln(self) -> f32 {
-        unsafe { intrinsics::logf32(self) }
-    }
-
-    /// Returns the logarithm of the number with respect to an arbitrary base
-    #[inline]
-    fn log(self, base: f32) -> f32 { self.ln() / base.ln() }
-
-    /// Returns the base 2 logarithm of the number
-    #[inline]
-    fn log2(self) -> f32 {
-        unsafe { intrinsics::log2f32(self) }
-    }
-
-    /// Returns the base 10 logarithm of the number
-    #[inline]
-    fn log10(self) -> f32 {
-        unsafe { intrinsics::log10f32(self) }
-    }
-
     /// Returns the natural logarithm of the number plus `1` (`ln(1+n)`) more
     /// accurately than if the operations were performed separately
     #[inline]
@@ -486,17 +231,6 @@ fn acosh(self) -> f32 {
     fn atanh(self) -> f32 {
         0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
     }
-
-    /// Converts to degrees, assuming the number is in radians
-    #[inline]
-    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 = Float::pi();
-        self * (value / 180.0f32)
-    }
 }
 
 //
index c18ea5caba6298c3a1ce5fcefbc691262495137d..41aeb27362e7f4722b4a4c038f4e9e75f2ca6a44 100644 (file)
 use prelude::*;
 
 use from_str::FromStr;
-use intrinsics;
-use libc::{c_int};
-use mem;
-use num::{FPCategory, FPNaN, FPInfinite , FPZero, FPSubnormal, FPNormal};
-use num::{strconv};
+use libc::c_int;
+use num::strconv;
 use num;
 
 pub use core::f64::{RADIX, MANTISSA_DIGITS, DIGITS, EPSILON, MIN_VALUE};
@@ -77,82 +74,7 @@ mod cmath {
     }
 }
 
-impl Float for f64 {
-    #[inline]
-    fn nan() -> f64 { NAN }
-
-    #[inline]
-    fn infinity() -> f64 { INFINITY }
-
-    #[inline]
-    fn neg_infinity() -> f64 { NEG_INFINITY }
-
-    #[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;
-
-        let bits: u64 = unsafe { mem::transmute(self) };
-        match (bits & MAN_MASK, bits & EXP_MASK) {
-            (0, 0)        => FPZero,
-            (_, 0)        => FPSubnormal,
-            (0, EXP_MASK) => FPInfinite,
-            (_, EXP_MASK) => FPNaN,
-            _             => FPNormal,
-        }
-    }
-
-    #[inline]
-    fn mantissa_digits(_: Option<f64>) -> uint { MANTISSA_DIGITS }
-
-    #[inline]
-    fn digits(_: Option<f64>) -> uint { DIGITS }
-
-    #[inline]
-    fn epsilon() -> f64 { EPSILON }
-
-    #[inline]
-    fn min_exp(_: Option<f64>) -> int { MIN_EXP }
-
-    #[inline]
-    fn max_exp(_: Option<f64>) -> int { MAX_EXP }
-
-    #[inline]
-    fn min_10_exp(_: Option<f64>) -> int { MIN_10_EXP }
-
-    #[inline]
-    fn max_10_exp(_: Option<f64>) -> int { MAX_10_EXP }
-
-    #[inline]
-    fn min_pos_value(_: Option<f64>) -> f64 { MIN_POS_VALUE }
-
+impl FloatMath for f64 {
     /// Constructs a floating point number by multiplying `x` by 2 raised to the
     /// power of `exp`
     #[inline]
@@ -174,21 +96,6 @@ fn frexp(self) -> (f64, int) {
         }
     }
 
-    /// Returns the mantissa, exponent and sign as integers.
-    fn integer_decode(self) -> (u64, i16, i8) {
-        let bits: u64 = unsafe { mem::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)
-    }
-
     /// Returns the next representable floating-point value in the direction of
     /// `other`.
     #[inline]
@@ -196,39 +103,6 @@ fn next_after(self, other: f64) -> f64 {
         unsafe { cmath::nextafter(self, other) }
     }
 
-    /// Round half-way cases toward `NEG_INFINITY`
-    #[inline]
-    fn floor(self) -> f64 {
-        unsafe { intrinsics::floorf64(self) }
-    }
-
-    /// Round half-way cases toward `INFINITY`
-    #[inline]
-    fn ceil(self) -> f64 {
-        unsafe { intrinsics::ceilf64(self) }
-    }
-
-    /// Round half-way cases away from `0.0`
-    #[inline]
-    fn round(self) -> f64 {
-        unsafe { intrinsics::roundf64(self) }
-    }
-
-    /// The integer part of the number (rounds towards `0.0`)
-    #[inline]
-    fn trunc(self) -> f64 {
-        unsafe { intrinsics::truncf64(self) }
-    }
-
-    /// The fractional part of the number, satisfying:
-    ///
-    /// ```rust
-    /// let x = 1.65f64;
-    /// assert!(x == x.trunc() + x.fract())
-    /// ```
-    #[inline]
-    fn fract(self) -> f64 { self - self.trunc() }
-
     #[inline]
     fn max(self, other: f64) -> f64 {
         unsafe { cmath::fmax(self, other) }
@@ -239,44 +113,6 @@ fn min(self, other: f64) -> f64 {
         unsafe { cmath::fmin(self, other) }
     }
 
-    /// 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 {
-        unsafe { intrinsics::fmaf64(self, a, b) }
-    }
-
-    /// The reciprocal (multiplicative inverse) of the number
-    #[inline]
-    fn recip(self) -> f64 { 1.0 / self }
-
-    #[inline]
-    fn powf(self, n: f64) -> f64 {
-        unsafe { intrinsics::powf64(self, n) }
-    }
-
-    #[inline]
-    fn powi(self, n: i32) -> f64 {
-        unsafe { intrinsics::powif64(self, n) }
-    }
-
-    /// sqrt(2.0)
-    #[inline]
-    fn sqrt2() -> f64 { consts::SQRT2 }
-
-    /// 1.0 / sqrt(2.0)
-    #[inline]
-    fn frac_1_sqrt2() -> f64 { consts::FRAC_1_SQRT2 }
-
-    #[inline]
-    fn sqrt(self) -> f64 {
-        unsafe { intrinsics::sqrtf64(self) }
-    }
-
-    #[inline]
-    fn rsqrt(self) -> f64 { self.sqrt().recip() }
-
     #[inline]
     fn cbrt(self) -> f64 {
         unsafe { cmath::cbrt(self) }
@@ -287,46 +123,6 @@ fn hypot(self, other: f64) -> f64 {
         unsafe { cmath::hypot(self, other) }
     }
 
-    /// Archimedes' constant
-    #[inline]
-    fn pi() -> f64 { consts::PI }
-
-    /// 2.0 * pi
-    #[inline]
-    fn two_pi() -> f64 { consts::PI_2 }
-
-    /// pi / 2.0
-    #[inline]
-    fn frac_pi_2() -> f64 { consts::FRAC_PI_2 }
-
-    /// pi / 3.0
-    #[inline]
-    fn frac_pi_3() -> f64 { consts::FRAC_PI_3 }
-
-    /// pi / 4.0
-    #[inline]
-    fn frac_pi_4() -> f64 { consts::FRAC_PI_4 }
-
-    /// pi / 6.0
-    #[inline]
-    fn frac_pi_6() -> f64 { consts::FRAC_PI_6 }
-
-    /// pi / 8.0
-    #[inline]
-    fn frac_pi_8() -> f64 { consts::FRAC_PI_8 }
-
-    /// 1.0 / pi
-    #[inline]
-    fn frac_1_pi() -> f64 { consts::FRAC_1_PI }
-
-    /// 2.0 / pi
-    #[inline]
-    fn frac_2_pi() -> f64 { consts::FRAC_2_PI }
-
-    /// 2.0 / sqrt(pi)
-    #[inline]
-    fn frac_2_sqrtpi() -> f64 { consts::FRAC_2_SQRTPI }
-
     #[inline]
     fn sin(self) -> f64 {
         unsafe { intrinsics::sinf64(self) }
@@ -368,38 +164,6 @@ fn sin_cos(self) -> (f64, f64) {
         (self.sin(), self.cos())
     }
 
-    /// Euler's number
-    #[inline]
-    fn e() -> f64 { consts::E }
-
-    /// log2(e)
-    #[inline]
-    fn log2_e() -> f64 { consts::LOG2_E }
-
-    /// log10(e)
-    #[inline]
-    fn log10_e() -> f64 { consts::LOG10_E }
-
-    /// ln(2.0)
-    #[inline]
-    fn ln_2() -> f64 { consts::LN_2 }
-
-    /// ln(10.0)
-    #[inline]
-    fn ln_10() -> f64 { consts::LN_10 }
-
-    /// Returns the exponential of the number
-    #[inline]
-    fn exp(self) -> f64 {
-        unsafe { intrinsics::expf64(self) }
-    }
-
-    /// Returns 2 raised to the power of the number
-    #[inline]
-    fn exp2(self) -> f64 {
-        unsafe { intrinsics::exp2f64(self) }
-    }
-
     /// Returns the exponential of the number, minus `1`, in a way that is
     /// accurate even if the number is close to zero
     #[inline]
@@ -407,28 +171,6 @@ fn exp_m1(self) -> f64 {
         unsafe { cmath::expm1(self) }
     }
 
-    /// Returns the natural logarithm of the number
-    #[inline]
-    fn ln(self) -> f64 {
-        unsafe { intrinsics::logf64(self) }
-    }
-
-    /// Returns the logarithm of the number with respect to an arbitrary base
-    #[inline]
-    fn log(self, base: f64) -> f64 { self.ln() / base.ln() }
-
-    /// Returns the base 2 logarithm of the number
-    #[inline]
-    fn log2(self) -> f64 {
-        unsafe { intrinsics::log2f64(self) }
-    }
-
-    /// Returns the base 10 logarithm of the number
-    #[inline]
-    fn log10(self) -> f64 {
-        unsafe { intrinsics::log10f64(self) }
-    }
-
     /// Returns the natural logarithm of the number plus `1` (`ln(1+n)`) more
     /// accurately than if the operations were performed separately
     #[inline]
@@ -495,17 +237,6 @@ fn acosh(self) -> f64 {
     fn atanh(self) -> f64 {
         0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
     }
-
-    /// Converts to degrees, assuming the number is in radians
-    #[inline]
-    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 = Float::pi();
-        self * (value / 180.0)
-    }
 }
 
 //
index 1efd7cad300bfca9b0144c0ba89ee4bfa11a58fe..3178fcbd66fdb8958e423a352f41942b134f2e33 100644 (file)
 pub use core::num::{from_int, from_i8, from_i16, from_i32, from_i64};
 pub use core::num::{from_uint, from_u8, from_u16, from_u32, from_u64};
 pub use core::num::{from_f32, from_f64};
+pub use core::num::{FPCategory, FPNaN, FPInfinite, FPZero, FPSubnormal};
+pub use core::num::{FPNormal, Float};
 
 pub mod strconv;
 
-/// Used for representing the classification of floating point numbers
-#[deriving(Eq, Show)]
-pub enum FPCategory {
-    /// "Not a Number", often obtained by dividing by zero
-    FPNaN,
-    /// Positive or negative infinity
-    FPInfinite ,
-    /// Positive or negative zero
-    FPZero,
-    /// De-normalized floating point representation (less precise than `FPNormal`)
-    FPSubnormal,
-    /// A regular floating point number
-    FPNormal,
-}
-
-/// Operations on primitive floating point numbers.
-// FIXME(#5527): In a future version of Rust, many of these functions will
-//               become constants.
-//
-// FIXME(#8888): Several of these functions have a parameter named
-//               `unused_self`. Removing it requires #8888 to be fixed.
-pub trait Float: Signed + Primitive {
-    /// Returns the NaN value.
-    fn nan() -> Self;
-    /// Returns the infinite value.
-    fn infinity() -> Self;
-    /// Returns the negative infinite value.
-    fn neg_infinity() -> Self;
-    /// Returns -0.0.
-    fn neg_zero() -> Self;
-
-    /// Returns true if this value is NaN and false otherwise.
-    fn is_nan(self) -> bool;
-    /// Returns true if this value is positive infinity or negative infinity and
-    /// false otherwise.
-    fn is_infinite(self) -> bool;
-    /// Returns true if this number is neither infinite nor NaN.
-    fn is_finite(self) -> bool;
-    /// Returns true if this number is neither zero, infinite, denormal, or NaN.
-    fn is_normal(self) -> bool;
-    /// Returns the category that this number falls into.
-    fn classify(self) -> FPCategory;
-
-    // FIXME (#5527): These should be associated constants
-
-    /// Returns the number of binary digits of mantissa that this type supports.
-    fn mantissa_digits(unused_self: Option<Self>) -> uint;
-    /// Returns the number of base-10 digits of precision that this type supports.
-    fn digits(unused_self: Option<Self>) -> uint;
-    /// Returns the difference between 1.0 and the smallest representable number larger than 1.0.
-    fn epsilon() -> Self;
-    /// Returns the minimum binary exponent that this type can represent.
-    fn min_exp(unused_self: Option<Self>) -> int;
-    /// Returns the maximum binary exponent that this type can represent.
-    fn max_exp(unused_self: Option<Self>) -> int;
-    /// Returns the minimum base-10 exponent that this type can represent.
-    fn min_10_exp(unused_self: Option<Self>) -> int;
-    /// Returns the maximum base-10 exponent that this type can represent.
-    fn max_10_exp(unused_self: Option<Self>) -> int;
-    /// Returns the smallest normalized positive number that this type can represent.
-    fn min_pos_value(unused_self: Option<Self>) -> Self;
-
+/// Mathematical operations on primitive floating point numbers.
+pub trait FloatMath: Float {
     /// Constructs a floating point number created by multiplying `x` by 2
     /// raised to the power of `exp`.
     fn ldexp(x: Self, exp: int) -> Self;
@@ -105,82 +47,22 @@ pub trait Float: Signed + Primitive {
     ///
     ///  * `0.5 <= abs(x) < 1.0`
     fn frexp(self) -> (Self, int);
-    /// Returns the mantissa, exponent and sign as integers, respectively.
-    fn integer_decode(self) -> (u64, i16, i8);
 
     /// Returns the next representable floating-point value in the direction of
     /// `other`.
     fn next_after(self, other: Self) -> Self;
 
-    /// Return the largest integer less than or equal to a number.
-    fn floor(self) -> Self;
-    /// Return the smallest integer greater than or equal to a number.
-    fn ceil(self) -> Self;
-    /// Return the nearest integer to a number. Round half-way cases away from
-    /// `0.0`.
-    fn round(self) -> Self;
-    /// Return the integer part of a number.
-    fn trunc(self) -> Self;
-    /// Return the fractional part of a number.
-    fn fract(self) -> Self;
-
     /// Returns the maximum of the two numbers.
     fn max(self, other: Self) -> Self;
     /// Returns the minimum of the two numbers.
     fn min(self, other: Self) -> 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.
-    fn mul_add(self, a: Self, b: Self) -> Self;
-    /// Take the reciprocal (inverse) of a number, `1/x`.
-    fn recip(self) -> Self;
-
-    /// Raise a number to an integer power.
-    ///
-    /// Using this function is generally faster than using `powf`
-    fn powi(self, n: i32) -> Self;
-    /// Raise a number to a floating point power.
-    fn powf(self, n: Self) -> Self;
-
-    /// sqrt(2.0).
-    fn sqrt2() -> Self;
-    /// 1.0 / sqrt(2.0).
-    fn frac_1_sqrt2() -> 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;
 
-    // FIXME (#5527): These should be associated constants
-
-    /// Archimedes' constant.
-    fn pi() -> Self;
-    /// 2.0 * pi.
-    fn two_pi() -> Self;
-    /// pi / 2.0.
-    fn frac_pi_2() -> Self;
-    /// pi / 3.0.
-    fn frac_pi_3() -> Self;
-    /// pi / 4.0.
-    fn frac_pi_4() -> Self;
-    /// pi / 6.0.
-    fn frac_pi_6() -> Self;
-    /// pi / 8.0.
-    fn frac_pi_8() -> Self;
-    /// 1.0 / pi.
-    fn frac_1_pi() -> Self;
-    /// 2.0 / pi.
-    fn frac_2_pi() -> Self;
-    /// 2.0 / sqrt(pi).
-    fn frac_2_sqrtpi() -> Self;
-
     /// Computes the sine of a number (in radians).
     fn sin(self) -> Self;
     /// Computes the cosine of a number (in radians).
@@ -206,32 +88,9 @@ pub trait Float: Signed + Primitive {
     /// `(sin(x), cos(x))`.
     fn sin_cos(self) -> (Self, Self);
 
-    /// Euler's number.
-    fn e() -> Self;
-    /// log2(e).
-    fn log2_e() -> Self;
-    /// log10(e).
-    fn log10_e() -> Self;
-    /// ln(2.0).
-    fn ln_2() -> Self;
-    /// ln(10.0).
-    fn ln_10() -> Self;
-
-    /// 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 exponential of the number, minus 1, in a way that is
     /// accurate even if the number is close to zero.
     fn exp_m1(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;
     /// Returns the natural logarithm of the number plus 1 (`ln(1+n)`) more
     /// accurately than if the operations were performed separately.
     fn ln_1p(self) -> Self;
@@ -248,11 +107,6 @@ pub trait Float: Signed + Primitive {
     fn acosh(self) -> Self;
     /// Inverse hyperbolic tangent function.
     fn atanh(self) -> Self;
-
-    /// Convert radians to degrees.
-    fn to_degrees(self) -> Self;
-    /// Convert degrees to radians.
-    fn to_radians(self) -> Self;
 }
 
 /// A generic trait for converting a value to a string with a radix (base)
index bf40a2d601fcca67d75aaeeead94ffc270b0ef2e..b3c768a519924c05f1cc63a10785374d8c8335c7 100644 (file)
@@ -38,7 +38,7 @@ fn local_sort<T: Float>(v: &mut [T]) {
 }
 
 /// Trait that provides simple descriptive statistics on a univariate set of numeric samples.
-pub trait Stats <T: Float + FromPrimitive>{
+pub trait Stats <T: FloatMath + FromPrimitive>{
 
     /// Sum of the samples.
     ///
@@ -143,7 +143,7 @@ pub struct Summary<T> {
     pub iqr: T,
 }
 
-impl<T: Float + FromPrimitive> Summary<T> {
+impl<T: FloatMath + FromPrimitive> Summary<T> {
 
     /// Construct a new summary of a sample set.
     pub fn new(samples: &[T]) -> Summary<T> {
@@ -164,7 +164,7 @@ pub fn new(samples: &[T]) -> Summary<T> {
     }
 }
 
-impl<'a,T: Float + FromPrimitive> Stats<T> for &'a [T] {
+impl<'a,T: FloatMath + FromPrimitive> Stats<T> for &'a [T] {
 
     // FIXME #11059 handle NaN, inf and overflow
     #[allow(deprecated_owned_vector)]