Skip to content

Commit

Permalink
Have floating point functions take their parameters by value.
Browse files Browse the repository at this point in the history
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]
  • Loading branch information
brendanzab committed Apr 19, 2014
1 parent fe47202 commit bed70a4
Show file tree
Hide file tree
Showing 9 changed files with 167 additions and 167 deletions.
4 changes: 2 additions & 2 deletions src/doc/guide-tasks.md
Expand Up @@ -306,7 +306,7 @@ be distributed on the available cores.
fn partial_sum(start: uint) -> f64 {
let mut local_sum = 0f64;
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
}
Expand Down Expand Up @@ -343,7 +343,7 @@ extern crate sync;
use sync::Arc;
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() {
Expand Down
4 changes: 2 additions & 2 deletions src/libnum/complex.rs
Expand Up @@ -82,15 +82,15 @@ impl<T: Clone + Float> Cmplx<T> {
/// Calculate |self|
#[inline]
pub fn norm(&self) -> T {
self.re.hypot(&self.im)
self.re.hypot(self.im)
}
}

impl<T: Clone + Float> Cmplx<T> {
/// Calculate the principal Arg of self.
#[inline]
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
/// * theta)`
Expand Down
12 changes: 6 additions & 6 deletions src/libnum/rational.rs
Expand Up @@ -631,19 +631,19 @@ mod test {

// f32
test(3.14159265359f32, ("13176795", "4194304"));
test(2f32.powf(&100.), ("1267650600228229401496703205376", "1"));
test(-2f32.powf(&100.), ("-1267650600228229401496703205376", "1"));
test(1.0 / 2f32.powf(&100.), ("1", "1267650600228229401496703205376"));
test(2f32.powf(100.), ("1267650600228229401496703205376", "1"));
test(-2f32.powf(100.), ("-1267650600228229401496703205376", "1"));
test(1.0 / 2f32.powf(100.), ("1", "1267650600228229401496703205376"));
test(684729.48391f32, ("1369459", "2"));
test(-8573.5918555f32, ("-4389679", "512"));

// f64
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(-8573.5918555, ("-4713381968463931", "549755813888"));
test(1.0 / 2f64.powf(&100.), ("1", "1267650600228229401496703205376"));
test(1.0 / 2f64.powf(100.), ("1", "1267650600228229401496703205376"));
}

#[test]
Expand Down
2 changes: 1 addition & 1 deletion src/librand/distributions/gamma.rs
Expand Up @@ -147,7 +147,7 @@ impl IndependentSample<f64> for GammaSmallShape {
fn ind_sample<R: Rng>(&self, rng: &mut R) -> 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 {
Expand Down
108 changes: 54 additions & 54 deletions src/libstd/num/f32.rs
Expand Up @@ -250,7 +250,7 @@ impl Bounded for f32 {
impl Primitive 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]
fn max(self, other: f32) -> f32 {
Expand All @@ -276,33 +276,33 @@ impl Float for f32 {

/// Returns `true` if the number is NaN
#[inline]
fn is_nan(&self) -> bool { *self != *self }
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()
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 {
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 {
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 {
fn classify(self) -> FPCategory {
static EXP_MASK: u32 = 0x7f800000;
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) {
(0, 0) => FPZero,
(_, 0) => FPSubnormal,
Expand Down Expand Up @@ -342,38 +342,38 @@ impl Float for f32 {
/// - `self = x * pow(2, exp)`
/// - `0.5 <= abs(x) < 1.0`
#[inline]
fn frexp(&self) -> (f32, int) {
fn frexp(self) -> (f32, int) {
unsafe {
let mut exp = 0;
let x = cmath::frexpf(*self, &mut exp);
let x = cmath::frexpf(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 { 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
/// than if the operations were performed separately
#[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
/// 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)} }
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`
#[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.
fn integer_decode(&self) -> (u64, i16, i8) {
fn integer_decode(self) -> (u64, i16, i8) {
let bits: u32 = unsafe {
::cast::transmute(*self)
::cast::transmute(self)
};
let sign: i8 = if bits >> 31 == 0 { 1 } else { -1 };
let mut exponent: i16 = ((bits >> 23) & 0xff) as i16;
Expand All @@ -389,19 +389,19 @@ impl Float for f32 {

/// Round half-way cases toward `NEG_INFINITY`
#[inline]
fn floor(&self) -> f32 { unsafe{intrinsics::floorf32(*self)} }
fn floor(self) -> f32 { unsafe{intrinsics::floorf32(self)} }

/// Round half-way cases toward `INFINITY`
#[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`
#[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`)
#[inline]
fn trunc(&self) -> f32 { unsafe{intrinsics::truncf32(*self)} }
fn trunc(self) -> f32 { unsafe{intrinsics::truncf32(self)} }

/// The fractional part of the number, satisfying:
///
Expand All @@ -410,7 +410,7 @@ impl Float for f32 {
/// assert!(x == x.trunc() + x.fract())
/// ```
#[inline]
fn fract(&self) -> f32 { *self - self.trunc() }
fn fract(self) -> f32 { self - self.trunc() }

/// Archimedes' constant
#[inline]
Expand Down Expand Up @@ -482,82 +482,82 @@ impl Float for f32 {

/// The reciprocal (multiplicative inverse) of the number
#[inline]
fn recip(&self) -> f32 { 1.0 / *self }
fn recip(self) -> f32 { 1.0 / self }

#[inline]
fn powf(&self, n: &f32) -> f32 { unsafe{intrinsics::powf32(*self, *n)} }
fn powf(self, n: f32) -> f32 { unsafe{intrinsics::powf32(self, n)} }

#[inline]
fn sqrt(&self) -> f32 { unsafe{intrinsics::sqrtf32(*self)} }
fn sqrt(self) -> f32 { unsafe{intrinsics::sqrtf32(self)} }

#[inline]
fn rsqrt(&self) -> f32 { self.sqrt().recip() }
fn rsqrt(self) -> f32 { self.sqrt().recip() }

#[inline]
fn cbrt(&self) -> f32 { unsafe{cmath::cbrtf(*self)} }
fn cbrt(self) -> f32 { unsafe{cmath::cbrtf(self)} }

#[inline]
fn hypot(&self, other: &f32) -> f32 { unsafe{cmath::hypotf(*self, *other)} }
fn hypot(self, other: f32) -> f32 { unsafe{cmath::hypotf(self, other)} }

#[inline]
fn sin(&self) -> f32 { unsafe{intrinsics::sinf32(*self)} }
fn sin(self) -> f32 { unsafe{intrinsics::sinf32(self)} }

#[inline]
fn cos(&self) -> f32 { unsafe{intrinsics::cosf32(*self)} }
fn cos(self) -> f32 { unsafe{intrinsics::cosf32(self)} }

#[inline]
fn tan(&self) -> f32 { unsafe{cmath::tanf(*self)} }
fn tan(self) -> f32 { unsafe{cmath::tanf(self)} }

#[inline]
fn asin(&self) -> f32 { unsafe{cmath::asinf(*self)} }
fn asin(self) -> f32 { unsafe{cmath::asinf(self)} }

#[inline]
fn acos(&self) -> f32 { unsafe{cmath::acosf(*self)} }
fn acos(self) -> f32 { unsafe{cmath::acosf(self)} }

#[inline]
fn atan(&self) -> f32 { unsafe{cmath::atanf(*self)} }
fn atan(self) -> f32 { unsafe{cmath::atanf(self)} }

#[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
#[inline]
fn sin_cos(&self) -> (f32, f32) {
fn sin_cos(self) -> (f32, f32) {
(self.sin(), self.cos())
}

/// Returns the exponential of the number
#[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
#[inline]
fn exp2(&self) -> f32 { unsafe{intrinsics::exp2f32(*self)} }
fn exp2(self) -> f32 { unsafe{intrinsics::exp2f32(self)} }

/// Returns the natural logarithm of the number
#[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
#[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
#[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
#[inline]
fn log10(&self) -> f32 { unsafe{intrinsics::log10f32(*self)} }
fn log10(self) -> f32 { unsafe{intrinsics::log10f32(self)} }

#[inline]
fn sinh(&self) -> f32 { unsafe{cmath::sinhf(*self)} }
fn sinh(self) -> f32 { unsafe{cmath::sinhf(self)} }

#[inline]
fn cosh(&self) -> f32 { unsafe{cmath::coshf(*self)} }
fn cosh(self) -> f32 { unsafe{cmath::coshf(self)} }

#[inline]
fn tanh(&self) -> f32 { unsafe{cmath::tanhf(*self)} }
fn tanh(self) -> f32 { unsafe{cmath::tanhf(self)} }

/// Inverse hyperbolic sine
///
Expand All @@ -567,8 +567,8 @@ impl Float for f32 {
/// - `self` if `self` is `0.0`, `-0.0`, `INFINITY`, or `NEG_INFINITY`
/// - `NAN` if `self` is `NAN`
#[inline]
fn asinh(&self) -> f32 {
match *self {
fn asinh(self) -> f32 {
match self {
NEG_INFINITY => NEG_INFINITY,
x => (x + ((x * x) + 1.0).sqrt()).ln(),
}
Expand All @@ -582,8 +582,8 @@ impl Float for f32 {
/// - `INFINITY` if `self` is `INFINITY`
/// - `NAN` if `self` is `NAN` or `self < 1.0` (including `NEG_INFINITY`)
#[inline]
fn acosh(&self) -> f32 {
match *self {
fn acosh(self) -> f32 {
match self {
x if x < 1.0 => Float::nan(),
x => (x + ((x * x) - 1.0).sqrt()).ln(),
}
Expand All @@ -600,19 +600,19 @@ impl Float for f32 {
/// - `NAN` if the `self` is `NAN` or outside the domain of `-1.0 <= self <= 1.0`
/// (including `INFINITY` and `NEG_INFINITY`)
#[inline]
fn atanh(&self) -> f32 {
0.5 * ((2.0 * *self) / (1.0 - *self)).ln_1p()
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()) }
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 {
fn to_radians(self) -> f32 {
let value: f32 = Float::pi();
*self * (value / 180.0f32)
self * (value / 180.0f32)
}
}

Expand Down Expand Up @@ -1162,7 +1162,7 @@ mod tests {
fn test_integer_decode() {
assert_eq!(3.14159265359f32.integer_decode(), (13176795u64, -22i16, 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!(INFINITY.integer_decode(), (8388608u64, 105i16, 1i8));
Expand Down

0 comments on commit bed70a4

Please sign in to comment.