auto merge of #13597 : bjz/rust/float-api, r=brson
This pull request: - Merges the `Round` trait into the `Float` trait, continuing issue #10387. - Has floating point functions take their parameters by value. - Cleans up the formatting and organisation in the definition and implementations of the `Float` trait. More information on the breaking changes can be found in the commit messages.
This commit is contained in:
commit
30fe55066a
@ -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() {
|
||||||
|
@ -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)`
|
||||||
|
@ -15,7 +15,7 @@ use Integer;
|
|||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::from_str::FromStr;
|
use std::from_str::FromStr;
|
||||||
use std::num::{Zero,One,ToStrRadix,FromStrRadix,Round};
|
use std::num::{Zero, One, ToStrRadix, FromStrRadix};
|
||||||
use bigint::{BigInt, BigUint, Sign, Plus, Minus};
|
use bigint::{BigInt, BigUint, Sign, Plus, Minus};
|
||||||
|
|
||||||
/// Represents the ratio between 2 numbers.
|
/// Represents the ratio between 2 numbers.
|
||||||
@ -113,6 +113,40 @@ impl<T: Clone + Integer + Ord>
|
|||||||
pub fn recip(&self) -> Ratio<T> {
|
pub fn recip(&self) -> Ratio<T> {
|
||||||
Ratio::new_raw(self.denom.clone(), self.numer.clone())
|
Ratio::new_raw(self.denom.clone(), self.numer.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn floor(&self) -> Ratio<T> {
|
||||||
|
if *self < Zero::zero() {
|
||||||
|
Ratio::from_integer((self.numer - self.denom + One::one()) / self.denom)
|
||||||
|
} else {
|
||||||
|
Ratio::from_integer(self.numer / self.denom)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ceil(&self) -> Ratio<T> {
|
||||||
|
if *self < Zero::zero() {
|
||||||
|
Ratio::from_integer(self.numer / self.denom)
|
||||||
|
} else {
|
||||||
|
Ratio::from_integer((self.numer + self.denom - One::one()) / self.denom)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn round(&self) -> Ratio<T> {
|
||||||
|
if *self < Zero::zero() {
|
||||||
|
Ratio::from_integer((self.numer - self.denom + One::one()) / self.denom)
|
||||||
|
} else {
|
||||||
|
Ratio::from_integer((self.numer + self.denom - One::one()) / self.denom)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn trunc(&self) -> Ratio<T> {
|
||||||
|
Ratio::from_integer(self.numer / self.denom)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fract(&self) -> Ratio<T> {
|
||||||
|
Ratio::new_raw(self.numer % self.denom, self.denom.clone())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ratio<BigInt> {
|
impl Ratio<BigInt> {
|
||||||
@ -238,45 +272,6 @@ impl<T: Clone + Integer + Ord>
|
|||||||
impl<T: Clone + Integer + Ord>
|
impl<T: Clone + Integer + Ord>
|
||||||
Num for Ratio<T> {}
|
Num for Ratio<T> {}
|
||||||
|
|
||||||
/* Utils */
|
|
||||||
impl<T: Clone + Integer + Ord>
|
|
||||||
Round for Ratio<T> {
|
|
||||||
|
|
||||||
fn floor(&self) -> Ratio<T> {
|
|
||||||
if *self < Zero::zero() {
|
|
||||||
Ratio::from_integer((self.numer - self.denom + One::one()) / self.denom)
|
|
||||||
} else {
|
|
||||||
Ratio::from_integer(self.numer / self.denom)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn ceil(&self) -> Ratio<T> {
|
|
||||||
if *self < Zero::zero() {
|
|
||||||
Ratio::from_integer(self.numer / self.denom)
|
|
||||||
} else {
|
|
||||||
Ratio::from_integer((self.numer + self.denom - One::one()) / self.denom)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn round(&self) -> Ratio<T> {
|
|
||||||
if *self < Zero::zero() {
|
|
||||||
Ratio::from_integer((self.numer - self.denom + One::one()) / self.denom)
|
|
||||||
} else {
|
|
||||||
Ratio::from_integer((self.numer + self.denom - One::one()) / self.denom)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn trunc(&self) -> Ratio<T> {
|
|
||||||
Ratio::from_integer(self.numer / self.denom)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fract(&self) -> Ratio<T> {
|
|
||||||
Ratio::new_raw(self.numer % self.denom, self.denom.clone())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* String conversions */
|
/* String conversions */
|
||||||
impl<T: fmt::Show> fmt::Show for Ratio<T> {
|
impl<T: fmt::Show> fmt::Show for Ratio<T> {
|
||||||
/// Renders as `numer/denom`.
|
/// Renders as `numer/denom`.
|
||||||
@ -636,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]
|
||||||
|
@ -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 {
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
use prelude::*;
|
use prelude::*;
|
||||||
|
|
||||||
|
use cast;
|
||||||
use default::Default;
|
use default::Default;
|
||||||
use from_str::FromStr;
|
use from_str::FromStr;
|
||||||
use libc::{c_int};
|
use libc::{c_int};
|
||||||
@ -216,12 +217,17 @@ impl Neg<f32> for f32 {
|
|||||||
impl Signed for f32 {
|
impl Signed for f32 {
|
||||||
/// Computes the absolute value. Returns `NAN` if the number is `NAN`.
|
/// Computes the absolute value. Returns `NAN` if the number is `NAN`.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn abs(&self) -> f32 { unsafe{intrinsics::fabsf32(*self)} }
|
fn abs(&self) -> f32 {
|
||||||
|
unsafe { intrinsics::fabsf32(*self) }
|
||||||
|
}
|
||||||
|
|
||||||
/// The positive difference of two numbers. Returns `0.0` if the number is less than or
|
/// The positive difference of two numbers. Returns `0.0` if the number is
|
||||||
/// equal to `other`, otherwise the difference between`self` and `other` is returned.
|
/// less than or equal to `other`, otherwise the difference between`self`
|
||||||
|
/// and `other` is returned.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn abs_sub(&self, other: &f32) -> f32 { unsafe{cmath::fdimf(*self, *other)} }
|
fn abs_sub(&self, other: &f32) -> f32 {
|
||||||
|
unsafe { cmath::fdimf(*self, *other) }
|
||||||
|
}
|
||||||
|
|
||||||
/// # Returns
|
/// # Returns
|
||||||
///
|
///
|
||||||
@ -230,7 +236,9 @@ impl Signed for f32 {
|
|||||||
/// - `NAN` if the number is NaN
|
/// - `NAN` if the number is NaN
|
||||||
#[inline]
|
#[inline]
|
||||||
fn signum(&self) -> f32 {
|
fn signum(&self) -> f32 {
|
||||||
if self.is_nan() { NAN } else { unsafe{intrinsics::copysignf32(1.0, *self)} }
|
if self.is_nan() { NAN } else {
|
||||||
|
unsafe { intrinsics::copysignf32(1.0, *self) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if the number is positive, including `+0.0` and `INFINITY`
|
/// Returns `true` if the number is positive, including `+0.0` and `INFINITY`
|
||||||
@ -242,33 +250,6 @@ impl Signed for f32 {
|
|||||||
fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == NEG_INFINITY }
|
fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == NEG_INFINITY }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Round for f32 {
|
|
||||||
/// 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() }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Bounded for f32 {
|
impl Bounded for f32 {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn min_value() -> f32 { 1.17549435e-38 }
|
fn min_value() -> f32 { 1.17549435e-38 }
|
||||||
@ -280,18 +261,6 @@ 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)} }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn max(self, other: f32) -> f32 {
|
|
||||||
unsafe { cmath::fmaxf(self, other) }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn min(self, other: f32) -> f32 {
|
|
||||||
unsafe { cmath::fminf(self, other) }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn nan() -> f32 { 0.0 / 0.0 }
|
fn nan() -> f32 { 0.0 / 0.0 }
|
||||||
|
|
||||||
@ -306,33 +275,34 @@ 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
|
||||||
/// be tested, it is generally faster to use the specific predicate instead.
|
/// is going to be tested, it is generally faster to use the specific
|
||||||
fn classify(&self) -> FPCategory {
|
/// predicate instead.
|
||||||
|
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,
|
||||||
@ -363,48 +333,30 @@ impl Float for f32 {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn max_10_exp(_: Option<f32>) -> int { 38 }
|
fn max_10_exp(_: Option<f32>) -> int { 38 }
|
||||||
|
|
||||||
/// Constructs a floating point number by multiplying `x` by 2 raised to the power of `exp`
|
/// Constructs a floating point number by multiplying `x` by 2 raised to the
|
||||||
|
/// power of `exp`
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ldexp(x: f32, exp: int) -> f32 { unsafe{cmath::ldexpf(x, exp as c_int)} }
|
fn ldexp(x: f32, exp: int) -> f32 {
|
||||||
|
unsafe { cmath::ldexpf(x, exp as c_int) }
|
||||||
|
}
|
||||||
|
|
||||||
/// Breaks the number into a normalized fraction and a base-2 exponent, satisfying:
|
/// Breaks the number into a normalized fraction and a base-2 exponent,
|
||||||
|
/// satisfying:
|
||||||
///
|
///
|
||||||
/// - `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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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)} }
|
|
||||||
|
|
||||||
/// 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)} }
|
|
||||||
|
|
||||||
/// 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)} }
|
|
||||||
|
|
||||||
/// 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)} }
|
|
||||||
|
|
||||||
/// 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;
|
||||||
let mantissa = if exponent == 0 {
|
let mantissa = if exponent == 0 {
|
||||||
@ -417,6 +369,103 @@ impl Float for f32 {
|
|||||||
(mantissa as u64, exponent, sign)
|
(mantissa as u64, exponent, sign)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
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 { 1.41421356237309504880168872420969808 }
|
||||||
|
|
||||||
|
/// 1.0 / sqrt(2.0)
|
||||||
|
#[inline]
|
||||||
|
fn frac_1_sqrt2() -> f32 { 0.707106781186547524400844362104849039 }
|
||||||
|
|
||||||
|
#[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) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn hypot(self, other: f32) -> f32 {
|
||||||
|
unsafe { cmath::hypotf(self, other) }
|
||||||
|
}
|
||||||
|
|
||||||
/// Archimedes' constant
|
/// Archimedes' constant
|
||||||
#[inline]
|
#[inline]
|
||||||
fn pi() -> f32 { 3.14159265358979323846264338327950288 }
|
fn pi() -> f32 { 3.14159265358979323846264338327950288 }
|
||||||
@ -457,13 +506,46 @@ impl Float for f32 {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn frac_2_sqrtpi() -> f32 { 1.12837916709551257389615890312154517 }
|
fn frac_2_sqrtpi() -> f32 { 1.12837916709551257389615890312154517 }
|
||||||
|
|
||||||
/// sqrt(2.0)
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sqrt2() -> f32 { 1.41421356237309504880168872420969808 }
|
fn sin(self) -> f32 {
|
||||||
|
unsafe { intrinsics::sinf32(self) }
|
||||||
|
}
|
||||||
|
|
||||||
/// 1.0 / sqrt(2.0)
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn frac_1_sqrt2() -> f32 { 0.707106781186547524400844362104849039 }
|
fn cos(self) -> f32 {
|
||||||
|
unsafe { intrinsics::cosf32(self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn tan(self) -> f32 {
|
||||||
|
unsafe { cmath::tanf(self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn asin(self) -> f32 {
|
||||||
|
unsafe { cmath::asinf(self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn acos(self) -> f32 {
|
||||||
|
unsafe { cmath::acosf(self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn atan(self) -> f32 {
|
||||||
|
unsafe { cmath::atanf(self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
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) {
|
||||||
|
(self.sin(), self.cos())
|
||||||
|
}
|
||||||
|
|
||||||
/// Euler's number
|
/// Euler's number
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -485,84 +567,68 @@ impl Float for f32 {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn ln_10() -> f32 { 2.30258509299404568401799145468436421 }
|
fn ln_10() -> f32 { 2.30258509299404568401799145468436421 }
|
||||||
|
|
||||||
/// The reciprocal (multiplicative inverse) of the number
|
|
||||||
#[inline]
|
|
||||||
fn recip(&self) -> f32 { 1.0 / *self }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn powf(&self, n: &f32) -> f32 { unsafe{intrinsics::powf32(*self, *n)} }
|
|
||||||
|
|
||||||
#[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)} }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn hypot(&self, other: &f32) -> f32 { unsafe{cmath::hypotf(*self, *other)} }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn sin(&self) -> f32 { unsafe{intrinsics::sinf32(*self)} }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn cos(&self) -> f32 { unsafe{intrinsics::cosf32(*self)} }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn tan(&self) -> f32 { unsafe{cmath::tanf(*self)} }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn asin(&self) -> f32 { unsafe{cmath::asinf(*self)} }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn acos(&self) -> f32 { unsafe{cmath::acosf(*self)} }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn atan(&self) -> f32 { unsafe{cmath::atanf(*self)} }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
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) {
|
|
||||||
(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 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) }
|
||||||
|
}
|
||||||
|
|
||||||
/// 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) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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) }
|
||||||
|
}
|
||||||
|
|
||||||
#[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
|
||||||
///
|
///
|
||||||
@ -572,8 +638,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(),
|
||||||
}
|
}
|
||||||
@ -587,8 +653,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(),
|
||||||
}
|
}
|
||||||
@ -605,19 +671,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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1167,7 +1233,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));
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
use prelude::*;
|
use prelude::*;
|
||||||
|
|
||||||
|
use cast;
|
||||||
use default::Default;
|
use default::Default;
|
||||||
use from_str::FromStr;
|
use from_str::FromStr;
|
||||||
use libc::{c_int};
|
use libc::{c_int};
|
||||||
@ -224,12 +225,16 @@ impl Neg<f64> for f64 {
|
|||||||
impl Signed for f64 {
|
impl Signed for f64 {
|
||||||
/// Computes the absolute value. Returns `NAN` if the number is `NAN`.
|
/// Computes the absolute value. Returns `NAN` if the number is `NAN`.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn abs(&self) -> f64 { unsafe{intrinsics::fabsf64(*self)} }
|
fn abs(&self) -> f64 {
|
||||||
|
unsafe { intrinsics::fabsf64(*self) }
|
||||||
|
}
|
||||||
|
|
||||||
/// The positive difference of two numbers. Returns `0.0` if the number is less than or
|
/// The positive difference of two numbers. Returns `0.0` if the number is less than or
|
||||||
/// equal to `other`, otherwise the difference between`self` and `other` is returned.
|
/// equal to `other`, otherwise the difference between`self` and `other` is returned.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn abs_sub(&self, other: &f64) -> f64 { unsafe{cmath::fdim(*self, *other)} }
|
fn abs_sub(&self, other: &f64) -> f64 {
|
||||||
|
unsafe { cmath::fdim(*self, *other) }
|
||||||
|
}
|
||||||
|
|
||||||
/// # Returns
|
/// # Returns
|
||||||
///
|
///
|
||||||
@ -238,7 +243,9 @@ impl Signed for f64 {
|
|||||||
/// - `NAN` if the number is NaN
|
/// - `NAN` if the number is NaN
|
||||||
#[inline]
|
#[inline]
|
||||||
fn signum(&self) -> f64 {
|
fn signum(&self) -> f64 {
|
||||||
if self.is_nan() { NAN } else { unsafe{intrinsics::copysignf64(1.0, *self)} }
|
if self.is_nan() { NAN } else {
|
||||||
|
unsafe { intrinsics::copysignf64(1.0, *self) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if the number is positive, including `+0.0` and `INFINITY`
|
/// Returns `true` if the number is positive, including `+0.0` and `INFINITY`
|
||||||
@ -250,33 +257,6 @@ impl Signed for f64 {
|
|||||||
fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == NEG_INFINITY }
|
fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == NEG_INFINITY }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Round for f64 {
|
|
||||||
/// 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() }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Bounded for f64 {
|
impl Bounded for f64 {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn min_value() -> f64 { 2.2250738585072014e-308 }
|
fn min_value() -> f64 { 2.2250738585072014e-308 }
|
||||||
@ -288,16 +268,6 @@ impl Bounded for f64 {
|
|||||||
impl Primitive for f64 {}
|
impl Primitive for f64 {}
|
||||||
|
|
||||||
impl Float for f64 {
|
impl Float for f64 {
|
||||||
#[inline]
|
|
||||||
fn max(self, other: f64) -> f64 {
|
|
||||||
unsafe { cmath::fmax(self, other) }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn min(self, other: f64) -> f64 {
|
|
||||||
unsafe { cmath::fmin(self, other) }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn nan() -> f64 { 0.0 / 0.0 }
|
fn nan() -> f64 { 0.0 / 0.0 }
|
||||||
|
|
||||||
@ -312,33 +282,34 @@ 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
|
||||||
/// be tested, it is generally faster to use the specific predicate instead.
|
/// is going to be tested, it is generally faster to use the specific
|
||||||
fn classify(&self) -> FPCategory {
|
/// predicate instead.
|
||||||
|
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,
|
||||||
@ -369,48 +340,30 @@ impl Float for f64 {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn max_10_exp(_: Option<f64>) -> int { 308 }
|
fn max_10_exp(_: Option<f64>) -> int { 308 }
|
||||||
|
|
||||||
/// Constructs a floating point number by multiplying `x` by 2 raised to the power of `exp`
|
/// Constructs a floating point number by multiplying `x` by 2 raised to the
|
||||||
|
/// power of `exp`
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ldexp(x: f64, exp: int) -> f64 { unsafe{cmath::ldexp(x, exp as c_int)} }
|
fn ldexp(x: f64, exp: int) -> f64 {
|
||||||
|
unsafe { cmath::ldexp(x, exp as c_int) }
|
||||||
|
}
|
||||||
|
|
||||||
/// Breaks the number into a normalized fraction and a base-2 exponent, satisfying:
|
/// Breaks the number into a normalized fraction and a base-2 exponent,
|
||||||
|
/// satisfying:
|
||||||
///
|
///
|
||||||
/// - `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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the exponential of the number, minus `1`, in a way that is accurate
|
|
||||||
/// even if the number is close to zero
|
|
||||||
#[inline]
|
|
||||||
fn exp_m1(&self) -> f64 { unsafe{cmath::expm1(*self)} }
|
|
||||||
|
|
||||||
/// Returns the natural logarithm of the number plus `1` (`ln(1+n)`) more accurately
|
|
||||||
/// than if the operations were performed separately
|
|
||||||
#[inline]
|
|
||||||
fn ln_1p(&self) -> f64 { unsafe{cmath::log1p(*self)} }
|
|
||||||
|
|
||||||
/// Fused multiply-add. Computes `(self * a) + b` with only one rounding error. This
|
|
||||||
/// produces a more accurate result with better performance than a separate multiplication
|
|
||||||
/// operation followed by an add.
|
|
||||||
#[inline]
|
|
||||||
fn mul_add(&self, a: f64, b: f64) -> f64 { unsafe{intrinsics::fmaf64(*self, a, b)} }
|
|
||||||
|
|
||||||
/// Returns the next representable floating-point value in the direction of `other`
|
|
||||||
#[inline]
|
|
||||||
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;
|
||||||
let mantissa = if exponent == 0 {
|
let mantissa = if exponent == 0 {
|
||||||
@ -423,6 +376,104 @@ impl Float for f64 {
|
|||||||
(mantissa, exponent, sign)
|
(mantissa, exponent, sign)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the next representable floating-point value in the direction of
|
||||||
|
/// `other`.
|
||||||
|
#[inline]
|
||||||
|
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) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
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 { 1.41421356237309504880168872420969808 }
|
||||||
|
|
||||||
|
/// 1.0 / sqrt(2.0)
|
||||||
|
#[inline]
|
||||||
|
fn frac_1_sqrt2() -> f64 { 0.707106781186547524400844362104849039 }
|
||||||
|
|
||||||
|
#[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) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn hypot(self, other: f64) -> f64 {
|
||||||
|
unsafe { cmath::hypot(self, other) }
|
||||||
|
}
|
||||||
|
|
||||||
/// Archimedes' constant
|
/// Archimedes' constant
|
||||||
#[inline]
|
#[inline]
|
||||||
fn pi() -> f64 { 3.14159265358979323846264338327950288 }
|
fn pi() -> f64 { 3.14159265358979323846264338327950288 }
|
||||||
@ -463,13 +514,46 @@ impl Float for f64 {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn frac_2_sqrtpi() -> f64 { 1.12837916709551257389615890312154517 }
|
fn frac_2_sqrtpi() -> f64 { 1.12837916709551257389615890312154517 }
|
||||||
|
|
||||||
/// sqrt(2.0)
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sqrt2() -> f64 { 1.41421356237309504880168872420969808 }
|
fn sin(self) -> f64 {
|
||||||
|
unsafe { intrinsics::sinf64(self) }
|
||||||
|
}
|
||||||
|
|
||||||
/// 1.0 / sqrt(2.0)
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn frac_1_sqrt2() -> f64 { 0.707106781186547524400844362104849039 }
|
fn cos(self) -> f64 {
|
||||||
|
unsafe { intrinsics::cosf64(self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn tan(self) -> f64 {
|
||||||
|
unsafe { cmath::tan(self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn asin(self) -> f64 {
|
||||||
|
unsafe { cmath::asin(self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn acos(self) -> f64 {
|
||||||
|
unsafe { cmath::acos(self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn atan(self) -> f64 {
|
||||||
|
unsafe { cmath::atan(self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn atan2(self, other: f64) -> f64 {
|
||||||
|
unsafe { cmath::atan2(self, other) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Simultaneously computes the sine and cosine of the number
|
||||||
|
#[inline]
|
||||||
|
fn sin_cos(self) -> (f64, f64) {
|
||||||
|
(self.sin(), self.cos())
|
||||||
|
}
|
||||||
|
|
||||||
/// Euler's number
|
/// Euler's number
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -491,87 +575,68 @@ impl Float for f64 {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn ln_10() -> f64 { 2.30258509299404568401799145468436421 }
|
fn ln_10() -> f64 { 2.30258509299404568401799145468436421 }
|
||||||
|
|
||||||
/// 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)} }
|
|
||||||
|
|
||||||
#[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)} }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn hypot(&self, other: &f64) -> f64 { unsafe{cmath::hypot(*self, *other)} }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn sin(&self) -> f64 { unsafe{intrinsics::sinf64(*self)} }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn cos(&self) -> f64 { unsafe{intrinsics::cosf64(*self)} }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn tan(&self) -> f64 { unsafe{cmath::tan(*self)} }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn asin(&self) -> f64 { unsafe{cmath::asin(*self)} }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn acos(&self) -> f64 { unsafe{cmath::acos(*self)} }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn atan(&self) -> f64 { unsafe{cmath::atan(*self)} }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn atan2(&self, other: &f64) -> f64 { unsafe{cmath::atan2(*self, *other)} }
|
|
||||||
|
|
||||||
/// Simultaneously computes the sine and cosine of the number
|
|
||||||
#[inline]
|
|
||||||
fn sin_cos(&self) -> (f64, f64) {
|
|
||||||
(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 exponential of the number, minus `1`, in a way that is
|
||||||
|
/// accurate even if the number is close to zero
|
||||||
|
#[inline]
|
||||||
|
fn exp_m1(self) -> f64 {
|
||||||
|
unsafe { cmath::expm1(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) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the natural logarithm of the number plus `1` (`ln(1+n)`) more
|
||||||
|
/// accurately than if the operations were performed separately
|
||||||
|
#[inline]
|
||||||
|
fn ln_1p(self) -> f64 {
|
||||||
|
unsafe { cmath::log1p(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
|
||||||
///
|
///
|
||||||
@ -581,8 +646,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(),
|
||||||
}
|
}
|
||||||
@ -596,8 +661,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(),
|
||||||
}
|
}
|
||||||
@ -614,19 +679,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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1170,7 +1235,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));
|
||||||
|
@ -162,25 +162,6 @@ pub fn abs_sub<T: Signed>(x: T, y: T) -> T {
|
|||||||
/// A trait for values which cannot be negative
|
/// A trait for values which cannot be negative
|
||||||
pub trait Unsigned: Num {}
|
pub trait Unsigned: Num {}
|
||||||
|
|
||||||
/// A collection of rounding operations.
|
|
||||||
pub trait Round {
|
|
||||||
/// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Raises a value to the power of exp, using exponentiation by squaring.
|
/// Raises a value to the power of exp, using exponentiation by squaring.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
@ -353,217 +334,199 @@ pub enum FPCategory {
|
|||||||
//
|
//
|
||||||
// FIXME(#8888): Several of these functions have a parameter named
|
// FIXME(#8888): Several of these functions have a parameter named
|
||||||
// `unused_self`. Removing it requires #8888 to be fixed.
|
// `unused_self`. Removing it requires #8888 to be fixed.
|
||||||
pub trait Float: Signed + Round + Primitive {
|
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;
|
||||||
|
|
||||||
|
/// Returns the number of binary digits of mantissa that this type supports.
|
||||||
|
fn mantissa_digits(unused_self: Option<Self>) -> uint;
|
||||||
|
/// Returns the number of binary digits of exponent that this type supports.
|
||||||
|
fn digits(unused_self: Option<Self>) -> uint;
|
||||||
|
/// Returns the smallest positive number that this type can represent.
|
||||||
|
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;
|
||||||
|
|
||||||
|
/// Constructs a floating point number created by multiplying `x` by 2
|
||||||
|
/// raised to the power of `exp`.
|
||||||
|
fn ldexp(x: Self, exp: int) -> Self;
|
||||||
|
/// Breaks the number into a normalized fraction and a base-2 exponent,
|
||||||
|
/// satisfying:
|
||||||
|
///
|
||||||
|
/// * `self = x * pow(2, exp)`
|
||||||
|
///
|
||||||
|
/// * `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.
|
/// Returns the maximum of the two numbers.
|
||||||
fn max(self, other: Self) -> Self;
|
fn max(self, other: Self) -> Self;
|
||||||
/// Returns the minimum of the two numbers.
|
/// Returns the minimum of the two numbers.
|
||||||
fn min(self, other: Self) -> Self;
|
fn min(self, other: Self) -> Self;
|
||||||
|
|
||||||
/// Returns the NaN value.
|
/// Fused multiply-add. Computes `(self * a) + b` with only one rounding
|
||||||
fn nan() -> Self;
|
/// error. This produces a more accurate result with better performance than
|
||||||
|
/// a separate multiplication operation followed by an add.
|
||||||
/// Returns the infinite value.
|
fn mul_add(self, a: Self, b: Self) -> Self;
|
||||||
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;
|
|
||||||
|
|
||||||
/// Returns the number of binary digits of mantissa that this type supports.
|
|
||||||
fn mantissa_digits(unused_self: Option<Self>) -> uint;
|
|
||||||
|
|
||||||
/// Returns the number of binary digits of exponent that this type supports.
|
|
||||||
fn digits(unused_self: Option<Self>) -> uint;
|
|
||||||
|
|
||||||
/// Returns the smallest positive number that this type can represent.
|
|
||||||
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;
|
|
||||||
|
|
||||||
/// Constructs a floating point number created by multiplying `x` by 2 raised to the power of
|
|
||||||
/// `exp`.
|
|
||||||
fn ldexp(x: Self, exp: int) -> Self;
|
|
||||||
|
|
||||||
/// Breaks the number into a normalized fraction and a base-2 exponent, satisfying:
|
|
||||||
///
|
|
||||||
/// * `self = x * pow(2, exp)`
|
|
||||||
///
|
|
||||||
/// * `0.5 <= abs(x) < 1.0`
|
|
||||||
fn frexp(&self) -> (Self, int);
|
|
||||||
|
|
||||||
/// 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 plus 1 (`ln(1+n)`) more accurately than if the
|
|
||||||
/// operations were performed separately.
|
|
||||||
fn ln_1p(&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;
|
|
||||||
|
|
||||||
/// Returns the next representable floating-point value in the direction of `other`.
|
|
||||||
fn next_after(&self, other: Self) -> Self;
|
|
||||||
|
|
||||||
/// Returns the mantissa, exponent and sign as integers, respectively.
|
|
||||||
fn integer_decode(&self) -> (u64, i16, i8);
|
|
||||||
|
|
||||||
/// 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;
|
|
||||||
|
|
||||||
/// sqrt(2.0).
|
|
||||||
fn sqrt2() -> Self;
|
|
||||||
|
|
||||||
/// 1.0 / sqrt(2.0).
|
|
||||||
fn frac_1_sqrt2() -> 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;
|
|
||||||
|
|
||||||
/// 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.
|
|
||||||
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;
|
||||||
|
/// 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.
|
/// 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;
|
||||||
|
|
||||||
|
/// 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).
|
/// 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);
|
||||||
|
|
||||||
|
/// 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).
|
/// 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 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.
|
/// 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;
|
||||||
|
/// 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;
|
||||||
|
|
||||||
/// 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.
|
||||||
|
@ -15,7 +15,7 @@ use clone::Clone;
|
|||||||
use container::Container;
|
use container::Container;
|
||||||
use iter::Iterator;
|
use iter::Iterator;
|
||||||
use num::{NumCast, Zero, One, cast, Int};
|
use num::{NumCast, Zero, One, cast, Int};
|
||||||
use num::{Round, Float, FPNaN, FPInfinite, ToPrimitive};
|
use num::{Float, FPNaN, FPInfinite, ToPrimitive};
|
||||||
use num;
|
use num;
|
||||||
use ops::{Add, Sub, Mul, Div, Rem, Neg};
|
use ops::{Add, Sub, Mul, Div, Rem, Neg};
|
||||||
use option::{None, Option, Some};
|
use option::{None, Option, Some};
|
||||||
@ -258,7 +258,7 @@ pub fn int_to_str_bytes_common<T: Int>(num: T, radix: uint, sign: SignFormat, f:
|
|||||||
* - Fails if `radix` > 25 and `exp_format` is `ExpBin` due to conflict
|
* - Fails if `radix` > 25 and `exp_format` is `ExpBin` due to conflict
|
||||||
* between digit and exponent sign `'p'`.
|
* between digit and exponent sign `'p'`.
|
||||||
*/
|
*/
|
||||||
pub fn float_to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Float+Round+
|
pub fn float_to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Float+
|
||||||
Div<T,T>+Neg<T>+Rem<T,T>+Mul<T,T>>(
|
Div<T,T>+Neg<T>+Rem<T,T>+Mul<T,T>>(
|
||||||
num: T, radix: uint, negative_zero: bool,
|
num: T, radix: uint, negative_zero: bool,
|
||||||
sign: SignFormat, digits: SignificantDigits, exp_format: ExponentFormat, exp_upper: bool
|
sign: SignFormat, digits: SignificantDigits, exp_format: ExponentFormat, exp_upper: bool
|
||||||
@ -310,7 +310,7 @@ pub fn float_to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Float+Round+
|
|||||||
ExpNone => unreachable!()
|
ExpNone => unreachable!()
|
||||||
};
|
};
|
||||||
|
|
||||||
(num / exp_base.powf(&exp), cast::<T, i32>(exp).unwrap())
|
(num / exp_base.powf(exp), cast::<T, i32>(exp).unwrap())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -491,7 +491,7 @@ pub fn float_to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Float+Round+
|
|||||||
* `to_str_bytes_common()`, for details see there.
|
* `to_str_bytes_common()`, for details see there.
|
||||||
*/
|
*/
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn float_to_str_common<T:NumCast+Zero+One+Eq+Ord+NumStrConv+Float+Round+
|
pub fn float_to_str_common<T:NumCast+Zero+One+Eq+Ord+NumStrConv+Float+
|
||||||
Div<T,T>+Neg<T>+Rem<T,T>+Mul<T,T>>(
|
Div<T,T>+Neg<T>+Rem<T,T>+Mul<T,T>>(
|
||||||
num: T, radix: uint, negative_zero: bool,
|
num: T, radix: uint, negative_zero: bool,
|
||||||
sign: SignFormat, digits: SignificantDigits, exp_format: ExponentFormat, exp_capital: bool
|
sign: SignFormat, digits: SignificantDigits, exp_format: ExponentFormat, exp_capital: bool
|
||||||
|
@ -45,7 +45,7 @@ pub use iter::{FromIterator, Extendable};
|
|||||||
pub use iter::{Iterator, DoubleEndedIterator, RandomAccessIterator, CloneableIterator};
|
pub use iter::{Iterator, DoubleEndedIterator, RandomAccessIterator, CloneableIterator};
|
||||||
pub use iter::{OrdIterator, MutableDoubleEndedIterator, ExactSize};
|
pub use iter::{OrdIterator, MutableDoubleEndedIterator, ExactSize};
|
||||||
pub use num::{Num, NumCast, CheckedAdd, CheckedSub, CheckedMul};
|
pub use num::{Num, NumCast, CheckedAdd, CheckedSub, CheckedMul};
|
||||||
pub use num::{Signed, Unsigned, Round};
|
pub use num::{Signed, Unsigned};
|
||||||
pub use num::{Primitive, Int, Float, ToPrimitive, FromPrimitive};
|
pub use num::{Primitive, Int, Float, ToPrimitive, FromPrimitive};
|
||||||
pub use path::{GenericPath, Path, PosixPath, WindowsPath};
|
pub use path::{GenericPath, Path, PosixPath, WindowsPath};
|
||||||
pub use ptr::RawPtr;
|
pub use ptr::RawPtr;
|
||||||
|
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user