Have floating point functions take their parameters by value.

Make all of the methods in `std::num::Float` take `self` and their other parameters by value.

Some of the `Float` methods took their parameters by value, and others took them by reference. This standardises them to one convention. The `Float` trait is intended for the built in IEEE 754 numbers only so we don't have to worry about the trait serving types of larger sizes.

[breaking-change]
This commit is contained in:
Brendan Zabarauskas 2014-04-18 13:49:37 +10:00
parent fe47202034
commit bed70a42ec
9 changed files with 167 additions and 167 deletions

View File

@ -306,7 +306,7 @@ be distributed on the available cores.
fn partial_sum(start: uint) -> f64 { fn partial_sum(start: uint) -> f64 {
let mut local_sum = 0f64; let mut local_sum = 0f64;
for num in range(start*100000, (start+1)*100000) { for num in range(start*100000, (start+1)*100000) {
local_sum += (num as f64 + 1.0).powf(&-2.0); local_sum += (num as f64 + 1.0).powf(-2.0);
} }
local_sum local_sum
} }
@ -343,7 +343,7 @@ extern crate sync;
use sync::Arc; use sync::Arc;
fn pnorm(nums: &[f64], p: uint) -> f64 { fn pnorm(nums: &[f64], p: uint) -> f64 {
nums.iter().fold(0.0, |a,b| a+(*b).powf(&(p as f64)) ).powf(&(1.0 / (p as f64))) nums.iter().fold(0.0, |a, b| a + b.powf(p as f64)).powf(1.0 / (p as f64))
} }
fn main() { fn main() {

View File

@ -82,7 +82,7 @@ impl<T: Clone + Float> Cmplx<T> {
/// Calculate |self| /// Calculate |self|
#[inline] #[inline]
pub fn norm(&self) -> T { pub fn norm(&self) -> T {
self.re.hypot(&self.im) self.re.hypot(self.im)
} }
} }
@ -90,7 +90,7 @@ impl<T: Clone + Float> Cmplx<T> {
/// Calculate the principal Arg of self. /// Calculate the principal Arg of self.
#[inline] #[inline]
pub fn arg(&self) -> T { pub fn arg(&self) -> T {
self.im.atan2(&self.re) self.im.atan2(self.re)
} }
/// Convert to polar form (r, theta), such that `self = r * exp(i /// Convert to polar form (r, theta), such that `self = r * exp(i
/// * theta)` /// * theta)`

View File

@ -631,19 +631,19 @@ mod test {
// f32 // f32
test(3.14159265359f32, ("13176795", "4194304")); test(3.14159265359f32, ("13176795", "4194304"));
test(2f32.powf(&100.), ("1267650600228229401496703205376", "1")); test(2f32.powf(100.), ("1267650600228229401496703205376", "1"));
test(-2f32.powf(&100.), ("-1267650600228229401496703205376", "1")); test(-2f32.powf(100.), ("-1267650600228229401496703205376", "1"));
test(1.0 / 2f32.powf(&100.), ("1", "1267650600228229401496703205376")); test(1.0 / 2f32.powf(100.), ("1", "1267650600228229401496703205376"));
test(684729.48391f32, ("1369459", "2")); test(684729.48391f32, ("1369459", "2"));
test(-8573.5918555f32, ("-4389679", "512")); test(-8573.5918555f32, ("-4389679", "512"));
// f64 // f64
test(3.14159265359f64, ("3537118876014453", "1125899906842624")); test(3.14159265359f64, ("3537118876014453", "1125899906842624"));
test(2f64.powf(&100.), ("1267650600228229401496703205376", "1")); test(2f64.powf(100.), ("1267650600228229401496703205376", "1"));
test(-2f64.powf(&100.), ("-1267650600228229401496703205376", "1")); test(-2f64.powf(100.), ("-1267650600228229401496703205376", "1"));
test(684729.48391f64, ("367611342500051", "536870912")); test(684729.48391f64, ("367611342500051", "536870912"));
test(-8573.5918555, ("-4713381968463931", "549755813888")); test(-8573.5918555, ("-4713381968463931", "549755813888"));
test(1.0 / 2f64.powf(&100.), ("1", "1267650600228229401496703205376")); test(1.0 / 2f64.powf(100.), ("1", "1267650600228229401496703205376"));
} }
#[test] #[test]

View File

@ -147,7 +147,7 @@ impl IndependentSample<f64> for GammaSmallShape {
fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 { fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
let Open01(u) = rng.gen::<Open01<f64>>(); let Open01(u) = rng.gen::<Open01<f64>>();
self.large_shape.ind_sample(rng) * u.powf(&self.inv_shape) self.large_shape.ind_sample(rng) * u.powf(self.inv_shape)
} }
} }
impl IndependentSample<f64> for GammaLargeShape { impl IndependentSample<f64> for GammaLargeShape {

View File

@ -250,7 +250,7 @@ impl Bounded for f32 {
impl Primitive for f32 {} impl Primitive for f32 {}
impl Float for f32 { impl Float for f32 {
fn powi(&self, n: i32) -> f32 { unsafe{intrinsics::powif32(*self, n)} } fn powi(self, n: i32) -> f32 { unsafe{intrinsics::powif32(self, n)} }
#[inline] #[inline]
fn max(self, other: f32) -> f32 { fn max(self, other: f32) -> f32 {
@ -276,33 +276,33 @@ impl Float for f32 {
/// Returns `true` if the number is NaN /// Returns `true` if the number is NaN
#[inline] #[inline]
fn is_nan(&self) -> bool { *self != *self } fn is_nan(self) -> bool { self != self }
/// Returns `true` if the number is infinite /// Returns `true` if the number is infinite
#[inline] #[inline]
fn is_infinite(&self) -> bool { fn is_infinite(self) -> bool {
*self == Float::infinity() || *self == Float::neg_infinity() self == Float::infinity() || self == Float::neg_infinity()
} }
/// Returns `true` if the number is neither infinite or NaN /// Returns `true` if the number is neither infinite or NaN
#[inline] #[inline]
fn is_finite(&self) -> bool { fn is_finite(self) -> bool {
!(self.is_nan() || self.is_infinite()) !(self.is_nan() || self.is_infinite())
} }
/// Returns `true` if the number is neither zero, infinite, subnormal or NaN /// Returns `true` if the number is neither zero, infinite, subnormal or NaN
#[inline] #[inline]
fn is_normal(&self) -> bool { fn is_normal(self) -> bool {
self.classify() == FPNormal self.classify() == FPNormal
} }
/// Returns the floating point category of the number. If only one property is going to /// 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. /// be tested, it is generally faster to use the specific predicate instead.
fn classify(&self) -> FPCategory { fn classify(self) -> FPCategory {
static EXP_MASK: u32 = 0x7f800000; static EXP_MASK: u32 = 0x7f800000;
static MAN_MASK: u32 = 0x007fffff; static MAN_MASK: u32 = 0x007fffff;
let bits: u32 = unsafe {::cast::transmute(*self)}; let bits: u32 = unsafe {::cast::transmute(self)};
match (bits & MAN_MASK, bits & EXP_MASK) { match (bits & MAN_MASK, bits & EXP_MASK) {
(0, 0) => FPZero, (0, 0) => FPZero,
(_, 0) => FPSubnormal, (_, 0) => FPSubnormal,
@ -342,10 +342,10 @@ impl Float for f32 {
/// - `self = x * pow(2, exp)` /// - `self = x * pow(2, exp)`
/// - `0.5 <= abs(x) < 1.0` /// - `0.5 <= abs(x) < 1.0`
#[inline] #[inline]
fn frexp(&self) -> (f32, int) { fn frexp(self) -> (f32, int) {
unsafe { unsafe {
let mut exp = 0; let mut exp = 0;
let x = cmath::frexpf(*self, &mut exp); let x = cmath::frexpf(self, &mut exp);
(x, exp as int) (x, exp as int)
} }
} }
@ -353,27 +353,27 @@ impl Float for f32 {
/// Returns the exponential of the number, minus `1`, in a way that is accurate /// Returns the exponential of the number, minus `1`, in a way that is accurate
/// even if the number is close to zero /// even if the number is close to zero
#[inline] #[inline]
fn exp_m1(&self) -> f32 { unsafe{cmath::expm1f(*self)} } fn exp_m1(self) -> f32 { unsafe{cmath::expm1f(self)} }
/// Returns the natural logarithm of the number plus `1` (`ln(1+n)`) more accurately /// Returns the natural logarithm of the number plus `1` (`ln(1+n)`) more accurately
/// than if the operations were performed separately /// than if the operations were performed separately
#[inline] #[inline]
fn ln_1p(&self) -> f32 { unsafe{cmath::log1pf(*self)} } fn ln_1p(self) -> f32 { unsafe{cmath::log1pf(self)} }
/// Fused multiply-add. Computes `(self * a) + b` with only one rounding error. This /// 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 /// produces a more accurate result with better performance than a separate multiplication
/// operation followed by an add. /// operation followed by an add.
#[inline] #[inline]
fn mul_add(&self, a: f32, b: f32) -> f32 { unsafe{intrinsics::fmaf32(*self, a, b)} } fn mul_add(self, a: f32, b: f32) -> f32 { unsafe{intrinsics::fmaf32(self, a, b)} }
/// Returns the next representable floating-point value in the direction of `other` /// Returns the next representable floating-point value in the direction of `other`
#[inline] #[inline]
fn next_after(&self, other: f32) -> f32 { unsafe{cmath::nextafterf(*self, other)} } fn next_after(self, other: f32) -> f32 { unsafe{cmath::nextafterf(self, other)} }
/// Returns the mantissa, exponent and sign as integers. /// Returns the mantissa, exponent and sign as integers.
fn integer_decode(&self) -> (u64, i16, i8) { fn integer_decode(self) -> (u64, i16, i8) {
let bits: u32 = unsafe { let bits: u32 = unsafe {
::cast::transmute(*self) ::cast::transmute(self)
}; };
let sign: i8 = if bits >> 31 == 0 { 1 } else { -1 }; let sign: i8 = if bits >> 31 == 0 { 1 } else { -1 };
let mut exponent: i16 = ((bits >> 23) & 0xff) as i16; let mut exponent: i16 = ((bits >> 23) & 0xff) as i16;
@ -389,19 +389,19 @@ impl Float for f32 {
/// Round half-way cases toward `NEG_INFINITY` /// Round half-way cases toward `NEG_INFINITY`
#[inline] #[inline]
fn floor(&self) -> f32 { unsafe{intrinsics::floorf32(*self)} } fn floor(self) -> f32 { unsafe{intrinsics::floorf32(self)} }
/// Round half-way cases toward `INFINITY` /// Round half-way cases toward `INFINITY`
#[inline] #[inline]
fn ceil(&self) -> f32 { unsafe{intrinsics::ceilf32(*self)} } fn ceil(self) -> f32 { unsafe{intrinsics::ceilf32(self)} }
/// Round half-way cases away from `0.0` /// Round half-way cases away from `0.0`
#[inline] #[inline]
fn round(&self) -> f32 { unsafe{intrinsics::roundf32(*self)} } fn round(self) -> f32 { unsafe{intrinsics::roundf32(self)} }
/// The integer part of the number (rounds towards `0.0`) /// The integer part of the number (rounds towards `0.0`)
#[inline] #[inline]
fn trunc(&self) -> f32 { unsafe{intrinsics::truncf32(*self)} } fn trunc(self) -> f32 { unsafe{intrinsics::truncf32(self)} }
/// The fractional part of the number, satisfying: /// The fractional part of the number, satisfying:
/// ///
@ -410,7 +410,7 @@ impl Float for f32 {
/// assert!(x == x.trunc() + x.fract()) /// assert!(x == x.trunc() + x.fract())
/// ``` /// ```
#[inline] #[inline]
fn fract(&self) -> f32 { *self - self.trunc() } fn fract(self) -> f32 { self - self.trunc() }
/// Archimedes' constant /// Archimedes' constant
#[inline] #[inline]
@ -482,82 +482,82 @@ impl Float for f32 {
/// The reciprocal (multiplicative inverse) of the number /// The reciprocal (multiplicative inverse) of the number
#[inline] #[inline]
fn recip(&self) -> f32 { 1.0 / *self } fn recip(self) -> f32 { 1.0 / self }
#[inline] #[inline]
fn powf(&self, n: &f32) -> f32 { unsafe{intrinsics::powf32(*self, *n)} } fn powf(self, n: f32) -> f32 { unsafe{intrinsics::powf32(self, n)} }
#[inline] #[inline]
fn sqrt(&self) -> f32 { unsafe{intrinsics::sqrtf32(*self)} } fn sqrt(self) -> f32 { unsafe{intrinsics::sqrtf32(self)} }
#[inline] #[inline]
fn rsqrt(&self) -> f32 { self.sqrt().recip() } fn rsqrt(self) -> f32 { self.sqrt().recip() }
#[inline] #[inline]
fn cbrt(&self) -> f32 { unsafe{cmath::cbrtf(*self)} } fn cbrt(self) -> f32 { unsafe{cmath::cbrtf(self)} }
#[inline] #[inline]
fn hypot(&self, other: &f32) -> f32 { unsafe{cmath::hypotf(*self, *other)} } fn hypot(self, other: f32) -> f32 { unsafe{cmath::hypotf(self, other)} }
#[inline] #[inline]
fn sin(&self) -> f32 { unsafe{intrinsics::sinf32(*self)} } fn sin(self) -> f32 { unsafe{intrinsics::sinf32(self)} }
#[inline] #[inline]
fn cos(&self) -> f32 { unsafe{intrinsics::cosf32(*self)} } fn cos(self) -> f32 { unsafe{intrinsics::cosf32(self)} }
#[inline] #[inline]
fn tan(&self) -> f32 { unsafe{cmath::tanf(*self)} } fn tan(self) -> f32 { unsafe{cmath::tanf(self)} }
#[inline] #[inline]
fn asin(&self) -> f32 { unsafe{cmath::asinf(*self)} } fn asin(self) -> f32 { unsafe{cmath::asinf(self)} }
#[inline] #[inline]
fn acos(&self) -> f32 { unsafe{cmath::acosf(*self)} } fn acos(self) -> f32 { unsafe{cmath::acosf(self)} }
#[inline] #[inline]
fn atan(&self) -> f32 { unsafe{cmath::atanf(*self)} } fn atan(self) -> f32 { unsafe{cmath::atanf(self)} }
#[inline] #[inline]
fn atan2(&self, other: &f32) -> f32 { unsafe{cmath::atan2f(*self, *other)} } fn atan2(self, other: f32) -> f32 { unsafe{cmath::atan2f(self, other)} }
/// Simultaneously computes the sine and cosine of the number /// Simultaneously computes the sine and cosine of the number
#[inline] #[inline]
fn sin_cos(&self) -> (f32, f32) { fn sin_cos(self) -> (f32, f32) {
(self.sin(), self.cos()) (self.sin(), self.cos())
} }
/// Returns the exponential of the number /// Returns the exponential of the number
#[inline] #[inline]
fn exp(&self) -> f32 { unsafe{intrinsics::expf32(*self)} } fn exp(self) -> f32 { unsafe{intrinsics::expf32(self)} }
/// Returns 2 raised to the power of the number /// Returns 2 raised to the power of the number
#[inline] #[inline]
fn exp2(&self) -> f32 { unsafe{intrinsics::exp2f32(*self)} } fn exp2(self) -> f32 { unsafe{intrinsics::exp2f32(self)} }
/// Returns the natural logarithm of the number /// Returns the natural logarithm of the number
#[inline] #[inline]
fn ln(&self) -> f32 { unsafe{intrinsics::logf32(*self)} } fn ln(self) -> f32 { unsafe{intrinsics::logf32(self)} }
/// Returns the logarithm of the number with respect to an arbitrary base /// Returns the logarithm of the number with respect to an arbitrary base
#[inline] #[inline]
fn log(&self, base: &f32) -> f32 { self.ln() / base.ln() } fn log(self, base: f32) -> f32 { self.ln() / base.ln() }
/// Returns the base 2 logarithm of the number /// Returns the base 2 logarithm of the number
#[inline] #[inline]
fn log2(&self) -> f32 { unsafe{intrinsics::log2f32(*self)} } fn log2(self) -> f32 { unsafe{intrinsics::log2f32(self)} }
/// Returns the base 10 logarithm of the number /// Returns the base 10 logarithm of the number
#[inline] #[inline]
fn log10(&self) -> f32 { unsafe{intrinsics::log10f32(*self)} } fn log10(self) -> f32 { unsafe{intrinsics::log10f32(self)} }
#[inline] #[inline]
fn sinh(&self) -> f32 { unsafe{cmath::sinhf(*self)} } fn sinh(self) -> f32 { unsafe{cmath::sinhf(self)} }
#[inline] #[inline]
fn cosh(&self) -> f32 { unsafe{cmath::coshf(*self)} } fn cosh(self) -> f32 { unsafe{cmath::coshf(self)} }
#[inline] #[inline]
fn tanh(&self) -> f32 { unsafe{cmath::tanhf(*self)} } fn tanh(self) -> f32 { unsafe{cmath::tanhf(self)} }
/// Inverse hyperbolic sine /// Inverse hyperbolic sine
/// ///
@ -567,8 +567,8 @@ impl Float for f32 {
/// - `self` if `self` is `0.0`, `-0.0`, `INFINITY`, or `NEG_INFINITY` /// - `self` if `self` is `0.0`, `-0.0`, `INFINITY`, or `NEG_INFINITY`
/// - `NAN` if `self` is `NAN` /// - `NAN` if `self` is `NAN`
#[inline] #[inline]
fn asinh(&self) -> f32 { fn asinh(self) -> f32 {
match *self { match self {
NEG_INFINITY => NEG_INFINITY, NEG_INFINITY => NEG_INFINITY,
x => (x + ((x * x) + 1.0).sqrt()).ln(), x => (x + ((x * x) + 1.0).sqrt()).ln(),
} }
@ -582,8 +582,8 @@ impl Float for f32 {
/// - `INFINITY` if `self` is `INFINITY` /// - `INFINITY` if `self` is `INFINITY`
/// - `NAN` if `self` is `NAN` or `self < 1.0` (including `NEG_INFINITY`) /// - `NAN` if `self` is `NAN` or `self < 1.0` (including `NEG_INFINITY`)
#[inline] #[inline]
fn acosh(&self) -> f32 { fn acosh(self) -> f32 {
match *self { match self {
x if x < 1.0 => Float::nan(), x if x < 1.0 => Float::nan(),
x => (x + ((x * x) - 1.0).sqrt()).ln(), x => (x + ((x * x) - 1.0).sqrt()).ln(),
} }
@ -600,19 +600,19 @@ impl Float for f32 {
/// - `NAN` if the `self` is `NAN` or outside the domain of `-1.0 <= self <= 1.0` /// - `NAN` if the `self` is `NAN` or outside the domain of `-1.0 <= self <= 1.0`
/// (including `INFINITY` and `NEG_INFINITY`) /// (including `INFINITY` and `NEG_INFINITY`)
#[inline] #[inline]
fn atanh(&self) -> f32 { fn atanh(self) -> f32 {
0.5 * ((2.0 * *self) / (1.0 - *self)).ln_1p() 0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
} }
/// Converts to degrees, assuming the number is in radians /// Converts to degrees, assuming the number is in radians
#[inline] #[inline]
fn to_degrees(&self) -> f32 { *self * (180.0f32 / Float::pi()) } fn to_degrees(self) -> f32 { self * (180.0f32 / Float::pi()) }
/// Converts to radians, assuming the number is in degrees /// Converts to radians, assuming the number is in degrees
#[inline] #[inline]
fn to_radians(&self) -> f32 { fn to_radians(self) -> f32 {
let value: f32 = Float::pi(); let value: f32 = Float::pi();
*self * (value / 180.0f32) self * (value / 180.0f32)
} }
} }
@ -1162,7 +1162,7 @@ mod tests {
fn test_integer_decode() { fn test_integer_decode() {
assert_eq!(3.14159265359f32.integer_decode(), (13176795u64, -22i16, 1i8)); assert_eq!(3.14159265359f32.integer_decode(), (13176795u64, -22i16, 1i8));
assert_eq!((-8573.5918555f32).integer_decode(), (8779358u64, -10i16, -1i8)); assert_eq!((-8573.5918555f32).integer_decode(), (8779358u64, -10i16, -1i8));
assert_eq!(2f32.powf(&100.0).integer_decode(), (8388608u64, 77i16, 1i8)); assert_eq!(2f32.powf(100.0).integer_decode(), (8388608u64, 77i16, 1i8));
assert_eq!(0f32.integer_decode(), (0u64, -150i16, 1i8)); assert_eq!(0f32.integer_decode(), (0u64, -150i16, 1i8));
assert_eq!((-0f32).integer_decode(), (0u64, -150i16, -1i8)); assert_eq!((-0f32).integer_decode(), (0u64, -150i16, -1i8));
assert_eq!(INFINITY.integer_decode(), (8388608u64, 105i16, 1i8)); assert_eq!(INFINITY.integer_decode(), (8388608u64, 105i16, 1i8));

View File

@ -282,33 +282,33 @@ impl Float for f64 {
/// Returns `true` if the number is NaN /// Returns `true` if the number is NaN
#[inline] #[inline]
fn is_nan(&self) -> bool { *self != *self } fn is_nan(self) -> bool { self != self }
/// Returns `true` if the number is infinite /// Returns `true` if the number is infinite
#[inline] #[inline]
fn is_infinite(&self) -> bool { fn is_infinite(self) -> bool {
*self == Float::infinity() || *self == Float::neg_infinity() self == Float::infinity() || self == Float::neg_infinity()
} }
/// Returns `true` if the number is neither infinite or NaN /// Returns `true` if the number is neither infinite or NaN
#[inline] #[inline]
fn is_finite(&self) -> bool { fn is_finite(self) -> bool {
!(self.is_nan() || self.is_infinite()) !(self.is_nan() || self.is_infinite())
} }
/// Returns `true` if the number is neither zero, infinite, subnormal or NaN /// Returns `true` if the number is neither zero, infinite, subnormal or NaN
#[inline] #[inline]
fn is_normal(&self) -> bool { fn is_normal(self) -> bool {
self.classify() == FPNormal self.classify() == FPNormal
} }
/// Returns the floating point category of the number. If only one property is going to /// 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. /// be tested, it is generally faster to use the specific predicate instead.
fn classify(&self) -> FPCategory { fn classify(self) -> FPCategory {
static EXP_MASK: u64 = 0x7ff0000000000000; static EXP_MASK: u64 = 0x7ff0000000000000;
static MAN_MASK: u64 = 0x000fffffffffffff; static MAN_MASK: u64 = 0x000fffffffffffff;
let bits: u64 = unsafe {::cast::transmute(*self)}; let bits: u64 = unsafe {::cast::transmute(self)};
match (bits & MAN_MASK, bits & EXP_MASK) { match (bits & MAN_MASK, bits & EXP_MASK) {
(0, 0) => FPZero, (0, 0) => FPZero,
(_, 0) => FPSubnormal, (_, 0) => FPSubnormal,
@ -348,10 +348,10 @@ impl Float for f64 {
/// - `self = x * pow(2, exp)` /// - `self = x * pow(2, exp)`
/// - `0.5 <= abs(x) < 1.0` /// - `0.5 <= abs(x) < 1.0`
#[inline] #[inline]
fn frexp(&self) -> (f64, int) { fn frexp(self) -> (f64, int) {
unsafe { unsafe {
let mut exp = 0; let mut exp = 0;
let x = cmath::frexp(*self, &mut exp); let x = cmath::frexp(self, &mut exp);
(x, exp as int) (x, exp as int)
} }
} }
@ -359,27 +359,27 @@ impl Float for f64 {
/// Returns the exponential of the number, minus `1`, in a way that is accurate /// Returns the exponential of the number, minus `1`, in a way that is accurate
/// even if the number is close to zero /// even if the number is close to zero
#[inline] #[inline]
fn exp_m1(&self) -> f64 { unsafe{cmath::expm1(*self)} } fn exp_m1(self) -> f64 { unsafe{cmath::expm1(self)} }
/// Returns the natural logarithm of the number plus `1` (`ln(1+n)`) more accurately /// Returns the natural logarithm of the number plus `1` (`ln(1+n)`) more accurately
/// than if the operations were performed separately /// than if the operations were performed separately
#[inline] #[inline]
fn ln_1p(&self) -> f64 { unsafe{cmath::log1p(*self)} } fn ln_1p(self) -> f64 { unsafe{cmath::log1p(self)} }
/// Fused multiply-add. Computes `(self * a) + b` with only one rounding error. This /// 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 /// produces a more accurate result with better performance than a separate multiplication
/// operation followed by an add. /// operation followed by an add.
#[inline] #[inline]
fn mul_add(&self, a: f64, b: f64) -> f64 { unsafe{intrinsics::fmaf64(*self, a, b)} } fn mul_add(self, a: f64, b: f64) -> f64 { unsafe{intrinsics::fmaf64(self, a, b)} }
/// Returns the next representable floating-point value in the direction of `other` /// Returns the next representable floating-point value in the direction of `other`
#[inline] #[inline]
fn next_after(&self, other: f64) -> f64 { unsafe{cmath::nextafter(*self, other)} } fn next_after(self, other: f64) -> f64 { unsafe{cmath::nextafter(self, other)} }
/// Returns the mantissa, exponent and sign as integers. /// Returns the mantissa, exponent and sign as integers.
fn integer_decode(&self) -> (u64, i16, i8) { fn integer_decode(self) -> (u64, i16, i8) {
let bits: u64 = unsafe { let bits: u64 = unsafe {
::cast::transmute(*self) ::cast::transmute(self)
}; };
let sign: i8 = if bits >> 63 == 0 { 1 } else { -1 }; let sign: i8 = if bits >> 63 == 0 { 1 } else { -1 };
let mut exponent: i16 = ((bits >> 52) & 0x7ff) as i16; let mut exponent: i16 = ((bits >> 52) & 0x7ff) as i16;
@ -395,19 +395,19 @@ impl Float for f64 {
/// Round half-way cases toward `NEG_INFINITY` /// Round half-way cases toward `NEG_INFINITY`
#[inline] #[inline]
fn floor(&self) -> f64 { unsafe{intrinsics::floorf64(*self)} } fn floor(self) -> f64 { unsafe{intrinsics::floorf64(self)} }
/// Round half-way cases toward `INFINITY` /// Round half-way cases toward `INFINITY`
#[inline] #[inline]
fn ceil(&self) -> f64 { unsafe{intrinsics::ceilf64(*self)} } fn ceil(self) -> f64 { unsafe{intrinsics::ceilf64(self)} }
/// Round half-way cases away from `0.0` /// Round half-way cases away from `0.0`
#[inline] #[inline]
fn round(&self) -> f64 { unsafe{intrinsics::roundf64(*self)} } fn round(self) -> f64 { unsafe{intrinsics::roundf64(self)} }
/// The integer part of the number (rounds towards `0.0`) /// The integer part of the number (rounds towards `0.0`)
#[inline] #[inline]
fn trunc(&self) -> f64 { unsafe{intrinsics::truncf64(*self)} } fn trunc(self) -> f64 { unsafe{intrinsics::truncf64(self)} }
/// The fractional part of the number, satisfying: /// The fractional part of the number, satisfying:
/// ///
@ -416,7 +416,7 @@ impl Float for f64 {
/// assert!(x == x.trunc() + x.fract()) /// assert!(x == x.trunc() + x.fract())
/// ``` /// ```
#[inline] #[inline]
fn fract(&self) -> f64 { *self - self.trunc() } fn fract(self) -> f64 { self - self.trunc() }
/// Archimedes' constant /// Archimedes' constant
#[inline] #[inline]
@ -488,85 +488,85 @@ impl Float for f64 {
/// The reciprocal (multiplicative inverse) of the number /// The reciprocal (multiplicative inverse) of the number
#[inline] #[inline]
fn recip(&self) -> f64 { 1.0 / *self } fn recip(self) -> f64 { 1.0 / self }
#[inline] #[inline]
fn powf(&self, n: &f64) -> f64 { unsafe{intrinsics::powf64(*self, *n)} } fn powf(self, n: f64) -> f64 { unsafe{intrinsics::powf64(self, n)} }
#[inline] #[inline]
fn powi(&self, n: i32) -> f64 { unsafe{intrinsics::powif64(*self, n)} } fn powi(self, n: i32) -> f64 { unsafe{intrinsics::powif64(self, n)} }
#[inline] #[inline]
fn sqrt(&self) -> f64 { unsafe{intrinsics::sqrtf64(*self)} } fn sqrt(self) -> f64 { unsafe{intrinsics::sqrtf64(self)} }
#[inline] #[inline]
fn rsqrt(&self) -> f64 { self.sqrt().recip() } fn rsqrt(self) -> f64 { self.sqrt().recip() }
#[inline] #[inline]
fn cbrt(&self) -> f64 { unsafe{cmath::cbrt(*self)} } fn cbrt(self) -> f64 { unsafe{cmath::cbrt(self)} }
#[inline] #[inline]
fn hypot(&self, other: &f64) -> f64 { unsafe{cmath::hypot(*self, *other)} } fn hypot(self, other: f64) -> f64 { unsafe{cmath::hypot(self, other)} }
#[inline] #[inline]
fn sin(&self) -> f64 { unsafe{intrinsics::sinf64(*self)} } fn sin(self) -> f64 { unsafe{intrinsics::sinf64(self)} }
#[inline] #[inline]
fn cos(&self) -> f64 { unsafe{intrinsics::cosf64(*self)} } fn cos(self) -> f64 { unsafe{intrinsics::cosf64(self)} }
#[inline] #[inline]
fn tan(&self) -> f64 { unsafe{cmath::tan(*self)} } fn tan(self) -> f64 { unsafe{cmath::tan(self)} }
#[inline] #[inline]
fn asin(&self) -> f64 { unsafe{cmath::asin(*self)} } fn asin(self) -> f64 { unsafe{cmath::asin(self)} }
#[inline] #[inline]
fn acos(&self) -> f64 { unsafe{cmath::acos(*self)} } fn acos(self) -> f64 { unsafe{cmath::acos(self)} }
#[inline] #[inline]
fn atan(&self) -> f64 { unsafe{cmath::atan(*self)} } fn atan(self) -> f64 { unsafe{cmath::atan(self)} }
#[inline] #[inline]
fn atan2(&self, other: &f64) -> f64 { unsafe{cmath::atan2(*self, *other)} } fn atan2(self, other: f64) -> f64 { unsafe{cmath::atan2(self, other)} }
/// Simultaneously computes the sine and cosine of the number /// Simultaneously computes the sine and cosine of the number
#[inline] #[inline]
fn sin_cos(&self) -> (f64, f64) { fn sin_cos(self) -> (f64, f64) {
(self.sin(), self.cos()) (self.sin(), self.cos())
} }
/// Returns the exponential of the number /// Returns the exponential of the number
#[inline] #[inline]
fn exp(&self) -> f64 { unsafe{intrinsics::expf64(*self)} } fn exp(self) -> f64 { unsafe{intrinsics::expf64(self)} }
/// Returns 2 raised to the power of the number /// Returns 2 raised to the power of the number
#[inline] #[inline]
fn exp2(&self) -> f64 { unsafe{intrinsics::exp2f64(*self)} } fn exp2(self) -> f64 { unsafe{intrinsics::exp2f64(self)} }
/// Returns the natural logarithm of the number /// Returns the natural logarithm of the number
#[inline] #[inline]
fn ln(&self) -> f64 { unsafe{intrinsics::logf64(*self)} } fn ln(self) -> f64 { unsafe{intrinsics::logf64(self)} }
/// Returns the logarithm of the number with respect to an arbitrary base /// Returns the logarithm of the number with respect to an arbitrary base
#[inline] #[inline]
fn log(&self, base: &f64) -> f64 { self.ln() / base.ln() } fn log(self, base: f64) -> f64 { self.ln() / base.ln() }
/// Returns the base 2 logarithm of the number /// Returns the base 2 logarithm of the number
#[inline] #[inline]
fn log2(&self) -> f64 { unsafe{intrinsics::log2f64(*self)} } fn log2(self) -> f64 { unsafe{intrinsics::log2f64(self)} }
/// Returns the base 10 logarithm of the number /// Returns the base 10 logarithm of the number
#[inline] #[inline]
fn log10(&self) -> f64 { unsafe{intrinsics::log10f64(*self)} } fn log10(self) -> f64 { unsafe{intrinsics::log10f64(self)} }
#[inline] #[inline]
fn sinh(&self) -> f64 { unsafe{cmath::sinh(*self)} } fn sinh(self) -> f64 { unsafe{cmath::sinh(self)} }
#[inline] #[inline]
fn cosh(&self) -> f64 { unsafe{cmath::cosh(*self)} } fn cosh(self) -> f64 { unsafe{cmath::cosh(self)} }
#[inline] #[inline]
fn tanh(&self) -> f64 { unsafe{cmath::tanh(*self)} } fn tanh(self) -> f64 { unsafe{cmath::tanh(self)} }
/// Inverse hyperbolic sine /// Inverse hyperbolic sine
/// ///
@ -576,8 +576,8 @@ impl Float for f64 {
/// - `self` if `self` is `0.0`, `-0.0`, `INFINITY`, or `NEG_INFINITY` /// - `self` if `self` is `0.0`, `-0.0`, `INFINITY`, or `NEG_INFINITY`
/// - `NAN` if `self` is `NAN` /// - `NAN` if `self` is `NAN`
#[inline] #[inline]
fn asinh(&self) -> f64 { fn asinh(self) -> f64 {
match *self { match self {
NEG_INFINITY => NEG_INFINITY, NEG_INFINITY => NEG_INFINITY,
x => (x + ((x * x) + 1.0).sqrt()).ln(), x => (x + ((x * x) + 1.0).sqrt()).ln(),
} }
@ -591,8 +591,8 @@ impl Float for f64 {
/// - `INFINITY` if `self` is `INFINITY` /// - `INFINITY` if `self` is `INFINITY`
/// - `NAN` if `self` is `NAN` or `self < 1.0` (including `NEG_INFINITY`) /// - `NAN` if `self` is `NAN` or `self < 1.0` (including `NEG_INFINITY`)
#[inline] #[inline]
fn acosh(&self) -> f64 { fn acosh(self) -> f64 {
match *self { match self {
x if x < 1.0 => Float::nan(), x if x < 1.0 => Float::nan(),
x => (x + ((x * x) - 1.0).sqrt()).ln(), x => (x + ((x * x) - 1.0).sqrt()).ln(),
} }
@ -609,19 +609,19 @@ impl Float for f64 {
/// - `NAN` if the `self` is `NAN` or outside the domain of `-1.0 <= self <= 1.0` /// - `NAN` if the `self` is `NAN` or outside the domain of `-1.0 <= self <= 1.0`
/// (including `INFINITY` and `NEG_INFINITY`) /// (including `INFINITY` and `NEG_INFINITY`)
#[inline] #[inline]
fn atanh(&self) -> f64 { fn atanh(self) -> f64 {
0.5 * ((2.0 * *self) / (1.0 - *self)).ln_1p() 0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
} }
/// Converts to degrees, assuming the number is in radians /// Converts to degrees, assuming the number is in radians
#[inline] #[inline]
fn to_degrees(&self) -> f64 { *self * (180.0f64 / Float::pi()) } fn to_degrees(self) -> f64 { self * (180.0f64 / Float::pi()) }
/// Converts to radians, assuming the number is in degrees /// Converts to radians, assuming the number is in degrees
#[inline] #[inline]
fn to_radians(&self) -> f64 { fn to_radians(self) -> f64 {
let value: f64 = Float::pi(); let value: f64 = Float::pi();
*self * (value / 180.0) self * (value / 180.0)
} }
} }
@ -1165,7 +1165,7 @@ mod tests {
fn test_integer_decode() { fn test_integer_decode() {
assert_eq!(3.14159265359f64.integer_decode(), (7074237752028906u64, -51i16, 1i8)); assert_eq!(3.14159265359f64.integer_decode(), (7074237752028906u64, -51i16, 1i8));
assert_eq!((-8573.5918555f64).integer_decode(), (4713381968463931u64, -39i16, -1i8)); assert_eq!((-8573.5918555f64).integer_decode(), (4713381968463931u64, -39i16, -1i8));
assert_eq!(2f64.powf(&100.0).integer_decode(), (4503599627370496u64, 48i16, 1i8)); assert_eq!(2f64.powf(100.0).integer_decode(), (4503599627370496u64, 48i16, 1i8));
assert_eq!(0f64.integer_decode(), (0u64, -1075i16, 1i8)); assert_eq!(0f64.integer_decode(), (0u64, -1075i16, 1i8));
assert_eq!((-0f64).integer_decode(), (0u64, -1075i16, -1i8)); assert_eq!((-0f64).integer_decode(), (0u64, -1075i16, -1i8));
assert_eq!(INFINITY.integer_decode(), (4503599627370496u64, 972i16, 1i8)); assert_eq!(INFINITY.integer_decode(), (4503599627370496u64, 972i16, 1i8));

View File

@ -347,19 +347,19 @@ pub trait Float: Signed + Primitive {
fn neg_zero() -> Self; fn neg_zero() -> Self;
/// Returns true if this value is NaN and false otherwise. /// Returns true if this value is NaN and false otherwise.
fn is_nan(&self) -> bool; fn is_nan(self) -> bool;
/// Returns true if this value is positive infinity or negative infinity and false otherwise. /// Returns true if this value is positive infinity or negative infinity and false otherwise.
fn is_infinite(&self) -> bool; fn is_infinite(self) -> bool;
/// Returns true if this number is neither infinite nor NaN. /// Returns true if this number is neither infinite nor NaN.
fn is_finite(&self) -> bool; fn is_finite(self) -> bool;
/// Returns true if this number is neither zero, infinite, denormal, or NaN. /// Returns true if this number is neither zero, infinite, denormal, or NaN.
fn is_normal(&self) -> bool; fn is_normal(self) -> bool;
/// Returns the category that this number falls into. /// Returns the category that this number falls into.
fn classify(&self) -> FPCategory; fn classify(self) -> FPCategory;
/// Returns the number of binary digits of mantissa that this type supports. /// Returns the number of binary digits of mantissa that this type supports.
fn mantissa_digits(unused_self: Option<Self>) -> uint; fn mantissa_digits(unused_self: Option<Self>) -> uint;
@ -391,42 +391,42 @@ pub trait Float: Signed + Primitive {
/// * `self = x * pow(2, exp)` /// * `self = x * pow(2, exp)`
/// ///
/// * `0.5 <= abs(x) < 1.0` /// * `0.5 <= abs(x) < 1.0`
fn frexp(&self) -> (Self, int); fn frexp(self) -> (Self, int);
/// Returns the exponential of the number, minus 1, in a way that is accurate even if the /// Returns the exponential of the number, minus 1, in a way that is accurate even if the
/// number is close to zero. /// number is close to zero.
fn exp_m1(&self) -> Self; fn exp_m1(self) -> Self;
/// Returns the natural logarithm of the number plus 1 (`ln(1+n)`) more accurately than if the /// Returns the natural logarithm of the number plus 1 (`ln(1+n)`) more accurately than if the
/// operations were performed separately. /// operations were performed separately.
fn ln_1p(&self) -> Self; fn ln_1p(self) -> Self;
/// Fused multiply-add. Computes `(self * a) + b` with only one rounding error. This produces a /// 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 /// more accurate result with better performance than a separate multiplication operation
/// followed by an add. /// followed by an add.
fn mul_add(&self, a: Self, b: Self) -> Self; fn mul_add(self, a: Self, b: Self) -> Self;
/// Returns the next representable floating-point value in the direction of `other`. /// Returns the next representable floating-point value in the direction of `other`.
fn next_after(&self, other: Self) -> Self; fn next_after(self, other: Self) -> Self;
/// Returns the mantissa, exponent and sign as integers, respectively. /// Returns the mantissa, exponent and sign as integers, respectively.
fn integer_decode(&self) -> (u64, i16, i8); fn integer_decode(self) -> (u64, i16, i8);
/// Return the largest integer less than or equal to a number. /// Return the largest integer less than or equal to a number.
fn floor(&self) -> Self; fn floor(self) -> Self;
/// Return the smallest integer greater than or equal to a number. /// Return the smallest integer greater than or equal to a number.
fn ceil(&self) -> Self; fn ceil(self) -> Self;
/// Return the nearest integer to a number. Round half-way cases away from /// Return the nearest integer to a number. Round half-way cases away from
/// `0.0`. /// `0.0`.
fn round(&self) -> Self; fn round(self) -> Self;
/// Return the integer part of a number. /// Return the integer part of a number.
fn trunc(&self) -> Self; fn trunc(self) -> Self;
/// Return the fractional part of a number. /// Return the fractional part of a number.
fn fract(&self) -> Self; fn fract(self) -> Self;
/// Archimedes' constant. /// Archimedes' constant.
fn pi() -> Self; fn pi() -> Self;
@ -480,81 +480,81 @@ pub trait Float: Signed + Primitive {
fn ln_10() -> Self; fn ln_10() -> Self;
/// Take the reciprocal (inverse) of a number, `1/x`. /// Take the reciprocal (inverse) of a number, `1/x`.
fn recip(&self) -> Self; fn recip(self) -> Self;
/// Raise a number to a power. /// Raise a number to a power.
fn powf(&self, n: &Self) -> Self; fn powf(self, n: Self) -> Self;
/// Raise a number to an integer power. /// Raise a number to an integer power.
/// ///
/// Using this function is generally faster than using `powf` /// Using this function is generally faster than using `powf`
fn powi(&self, n: i32) -> Self; fn powi(self, n: i32) -> Self;
/// Take the square root of a number. /// Take the square root of a number.
fn sqrt(&self) -> Self; fn sqrt(self) -> Self;
/// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`. /// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
fn rsqrt(&self) -> Self; fn rsqrt(self) -> Self;
/// Take the cubic root of a number. /// Take the cubic root of a number.
fn cbrt(&self) -> Self; fn cbrt(self) -> Self;
/// Calculate the length of the hypotenuse of a right-angle triangle given /// Calculate the length of the hypotenuse of a right-angle triangle given
/// legs of length `x` and `y`. /// legs of length `x` and `y`.
fn hypot(&self, other: &Self) -> Self; fn hypot(self, other: Self) -> Self;
/// Computes the sine of a number (in radians). /// Computes the sine of a number (in radians).
fn sin(&self) -> Self; fn sin(self) -> Self;
/// Computes the cosine of a number (in radians). /// Computes the cosine of a number (in radians).
fn cos(&self) -> Self; fn cos(self) -> Self;
/// Computes the tangent of a number (in radians). /// Computes the tangent of a number (in radians).
fn tan(&self) -> Self; fn tan(self) -> Self;
/// Computes the arcsine of a number. Return value is in radians in /// 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 /// the range [-pi/2, pi/2] or NaN if the number is outside the range
/// [-1, 1]. /// [-1, 1].
fn asin(&self) -> Self; fn asin(self) -> Self;
/// Computes the arccosine of a number. Return value is in radians in /// 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 /// the range [0, pi] or NaN if the number is outside the range
/// [-1, 1]. /// [-1, 1].
fn acos(&self) -> Self; fn acos(self) -> Self;
/// Computes the arctangent of a number. Return value is in radians in the /// Computes the arctangent of a number. Return value is in radians in the
/// range [-pi/2, pi/2]; /// range [-pi/2, pi/2];
fn atan(&self) -> Self; fn atan(self) -> Self;
/// Computes the four quadrant arctangent of a number, `y`, and another /// Computes the four quadrant arctangent of a number, `y`, and another
/// number `x`. Return value is in radians in the range [-pi, pi]. /// number `x`. Return value is in radians in the range [-pi, pi].
fn atan2(&self, other: &Self) -> Self; fn atan2(self, other: Self) -> Self;
/// Simultaneously computes the sine and cosine of the number, `x`. Returns /// Simultaneously computes the sine and cosine of the number, `x`. Returns
/// `(sin(x), cos(x))`. /// `(sin(x), cos(x))`.
fn sin_cos(&self) -> (Self, Self); fn sin_cos(self) -> (Self, Self);
/// Returns `e^(self)`, (the exponential function). /// Returns `e^(self)`, (the exponential function).
fn exp(&self) -> Self; fn exp(self) -> Self;
/// Returns 2 raised to the power of the number, `2^(self)`. /// Returns 2 raised to the power of the number, `2^(self)`.
fn exp2(&self) -> Self; fn exp2(self) -> Self;
/// Returns the natural logarithm of the number. /// Returns the natural logarithm of the number.
fn ln(&self) -> Self; fn ln(self) -> Self;
/// Returns the logarithm of the number with respect to an arbitrary base. /// Returns the logarithm of the number with respect to an arbitrary base.
fn log(&self, base: &Self) -> Self; fn log(self, base: Self) -> Self;
/// Returns the base 2 logarithm of the number. /// Returns the base 2 logarithm of the number.
fn log2(&self) -> Self; fn log2(self) -> Self;
/// Returns the base 10 logarithm of the number. /// Returns the base 10 logarithm of the number.
fn log10(&self) -> Self; fn log10(self) -> Self;
/// Hyperbolic sine function. /// Hyperbolic sine function.
fn sinh(&self) -> Self; fn sinh(self) -> Self;
/// Hyperbolic cosine function. /// Hyperbolic cosine function.
fn cosh(&self) -> Self; fn cosh(self) -> Self;
/// Hyperbolic tangent function. /// Hyperbolic tangent function.
fn tanh(&self) -> Self; fn tanh(self) -> Self;
/// Inverse hyperbolic sine function. /// Inverse hyperbolic sine function.
fn asinh(&self) -> Self; fn asinh(self) -> Self;
/// Inverse hyperbolic cosine function. /// Inverse hyperbolic cosine function.
fn acosh(&self) -> Self; fn acosh(self) -> Self;
/// Inverse hyperbolic tangent function. /// Inverse hyperbolic tangent function.
fn atanh(&self) -> Self; fn atanh(self) -> Self;
/// Convert radians to degrees. /// Convert radians to degrees.
fn to_degrees(&self) -> Self; fn to_degrees(self) -> Self;
/// Convert degrees to radians. /// Convert degrees to radians.
fn to_radians(&self) -> Self; fn to_radians(self) -> Self;
} }
/// A generic trait for converting a value to a number. /// A generic trait for converting a value to a number.

View File

@ -310,7 +310,7 @@ pub fn float_to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Float+
ExpNone => unreachable!() ExpNone => unreachable!()
}; };
(num / exp_base.powf(&exp), cast::<T, i32>(exp).unwrap()) (num / exp_base.powf(exp), cast::<T, i32>(exp).unwrap())
} }
} }
}; };

View File

@ -352,8 +352,8 @@ pub fn write_boxplot(w: &mut io::Writer, s: &Summary,
let (q1,q2,q3) = s.quartiles; let (q1,q2,q3) = s.quartiles;
// the .abs() handles the case where numbers are negative // the .abs() handles the case where numbers are negative
let lomag = (10.0_f64).powf(&(s.min.abs().log10().floor())); let lomag = 10.0_f64.powf(s.min.abs().log10().floor());
let himag = (10.0_f64).powf(&(s.max.abs().log10().floor())); let himag = 10.0_f64.powf(s.max.abs().log10().floor());
// need to consider when the limit is zero // need to consider when the limit is zero
let lo = if lomag == 0.0 { let lo = if lomag == 0.0 {