Add some f32 and f64 inherent methods in libcore
… previously in the unstable core::num::Float trait. Per https://github.com/rust-lang/rust/issues/32110#issuecomment-379503183, the `abs`, `signum`, and `powi` methods are *not* included for now since they rely on LLVM intrinsics and we haven’t determined yet whether those instrinsics lower to calls to libm functions on any platform.
This commit is contained in:
parent
f0705bf033
commit
8a374f2827
10 changed files with 611 additions and 559 deletions
|
@ -74,6 +74,7 @@ use core::iter::{FromIterator, FusedIterator, TrustedLen};
|
|||
use core::marker::PhantomData;
|
||||
use core::mem;
|
||||
#[cfg(not(test))]
|
||||
#[cfg(stage0)]
|
||||
use core::num::Float;
|
||||
use core::ops::Bound::{Excluded, Included, Unbounded};
|
||||
use core::ops::{Index, IndexMut, RangeBounds};
|
||||
|
|
|
@ -71,6 +71,7 @@
|
|||
#![feature(cfg_target_has_atomic)]
|
||||
#![feature(concat_idents)]
|
||||
#![feature(const_fn)]
|
||||
#![feature(core_float)]
|
||||
#![feature(custom_attribute)]
|
||||
#![feature(doc_cfg)]
|
||||
#![feature(doc_spotlight)]
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
use intrinsics;
|
||||
use mem;
|
||||
use num::Float;
|
||||
#[cfg(not(stage0))] use num::FpCategory;
|
||||
use num::FpCategory as Fp;
|
||||
|
||||
/// The radix or base of the internal representation of `f32`.
|
||||
|
@ -292,3 +293,286 @@ impl Float for f32 {
|
|||
unsafe { mem::transmute(v) }
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: remove (inline) this macro and the Float trait
|
||||
// when updating to a bootstrap compiler that has the new lang items.
|
||||
#[cfg_attr(stage0, macro_export)]
|
||||
#[unstable(feature = "core_float", issue = "32110")]
|
||||
macro_rules! f32_core_methods { () => {
|
||||
/// Returns `true` if this value is `NaN` and false otherwise.
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
/// let nan = f32::NAN;
|
||||
/// let f = 7.0_f32;
|
||||
///
|
||||
/// assert!(nan.is_nan());
|
||||
/// assert!(!f.is_nan());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_nan(self) -> bool { Float::is_nan(self) }
|
||||
|
||||
/// Returns `true` if this value is positive infinity or negative infinity and
|
||||
/// false otherwise.
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
/// let f = 7.0f32;
|
||||
/// let inf = f32::INFINITY;
|
||||
/// let neg_inf = f32::NEG_INFINITY;
|
||||
/// let nan = f32::NAN;
|
||||
///
|
||||
/// assert!(!f.is_infinite());
|
||||
/// assert!(!nan.is_infinite());
|
||||
///
|
||||
/// assert!(inf.is_infinite());
|
||||
/// assert!(neg_inf.is_infinite());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_infinite(self) -> bool { Float::is_infinite(self) }
|
||||
|
||||
/// Returns `true` if this number is neither infinite nor `NaN`.
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
/// let f = 7.0f32;
|
||||
/// let inf = f32::INFINITY;
|
||||
/// let neg_inf = f32::NEG_INFINITY;
|
||||
/// let nan = f32::NAN;
|
||||
///
|
||||
/// assert!(f.is_finite());
|
||||
///
|
||||
/// assert!(!nan.is_finite());
|
||||
/// assert!(!inf.is_finite());
|
||||
/// assert!(!neg_inf.is_finite());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_finite(self) -> bool { Float::is_finite(self) }
|
||||
|
||||
/// Returns `true` if the number is neither zero, infinite,
|
||||
/// [subnormal][subnormal], or `NaN`.
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
/// let min = f32::MIN_POSITIVE; // 1.17549435e-38f32
|
||||
/// let max = f32::MAX;
|
||||
/// let lower_than_min = 1.0e-40_f32;
|
||||
/// let zero = 0.0_f32;
|
||||
///
|
||||
/// assert!(min.is_normal());
|
||||
/// assert!(max.is_normal());
|
||||
///
|
||||
/// assert!(!zero.is_normal());
|
||||
/// assert!(!f32::NAN.is_normal());
|
||||
/// assert!(!f32::INFINITY.is_normal());
|
||||
/// // Values between `0` and `min` are Subnormal.
|
||||
/// assert!(!lower_than_min.is_normal());
|
||||
/// ```
|
||||
/// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_normal(self) -> bool { Float::is_normal(self) }
|
||||
|
||||
/// 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.
|
||||
///
|
||||
/// ```
|
||||
/// use std::num::FpCategory;
|
||||
/// use std::f32;
|
||||
///
|
||||
/// let num = 12.4_f32;
|
||||
/// let inf = f32::INFINITY;
|
||||
///
|
||||
/// assert_eq!(num.classify(), FpCategory::Normal);
|
||||
/// assert_eq!(inf.classify(), FpCategory::Infinite);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn classify(self) -> FpCategory { Float::classify(self) }
|
||||
|
||||
/// Returns `true` if and only if `self` has a positive sign, including `+0.0`, `NaN`s with
|
||||
/// positive sign bit and positive infinity.
|
||||
///
|
||||
/// ```
|
||||
/// let f = 7.0_f32;
|
||||
/// let g = -7.0_f32;
|
||||
///
|
||||
/// assert!(f.is_sign_positive());
|
||||
/// assert!(!g.is_sign_positive());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_sign_positive(self) -> bool { Float::is_sign_positive(self) }
|
||||
|
||||
/// Returns `true` if and only if `self` has a negative sign, including `-0.0`, `NaN`s with
|
||||
/// negative sign bit and negative infinity.
|
||||
///
|
||||
/// ```
|
||||
/// let f = 7.0f32;
|
||||
/// let g = -7.0f32;
|
||||
///
|
||||
/// assert!(!f.is_sign_negative());
|
||||
/// assert!(g.is_sign_negative());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_sign_negative(self) -> bool { Float::is_sign_negative(self) }
|
||||
|
||||
/// Takes the reciprocal (inverse) of a number, `1/x`.
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
/// let x = 2.0_f32;
|
||||
/// let abs_difference = (x.recip() - (1.0/x)).abs();
|
||||
///
|
||||
/// assert!(abs_difference <= f32::EPSILON);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn recip(self) -> f32 { Float::recip(self) }
|
||||
|
||||
/// Converts radians to degrees.
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32::{self, consts};
|
||||
///
|
||||
/// let angle = consts::PI;
|
||||
///
|
||||
/// let abs_difference = (angle.to_degrees() - 180.0).abs();
|
||||
///
|
||||
/// assert!(abs_difference <= f32::EPSILON);
|
||||
/// ```
|
||||
#[stable(feature = "f32_deg_rad_conversions", since="1.7.0")]
|
||||
#[inline]
|
||||
pub fn to_degrees(self) -> f32 { Float::to_degrees(self) }
|
||||
|
||||
/// Converts degrees to radians.
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32::{self, consts};
|
||||
///
|
||||
/// let angle = 180.0f32;
|
||||
///
|
||||
/// let abs_difference = (angle.to_radians() - consts::PI).abs();
|
||||
///
|
||||
/// assert!(abs_difference <= f32::EPSILON);
|
||||
/// ```
|
||||
#[stable(feature = "f32_deg_rad_conversions", since="1.7.0")]
|
||||
#[inline]
|
||||
pub fn to_radians(self) -> f32 { Float::to_radians(self) }
|
||||
|
||||
/// Returns the maximum of the two numbers.
|
||||
///
|
||||
/// ```
|
||||
/// let x = 1.0f32;
|
||||
/// let y = 2.0f32;
|
||||
///
|
||||
/// assert_eq!(x.max(y), y);
|
||||
/// ```
|
||||
///
|
||||
/// If one of the arguments is NaN, then the other argument is returned.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn max(self, other: f32) -> f32 {
|
||||
Float::max(self, other)
|
||||
}
|
||||
|
||||
/// Returns the minimum of the two numbers.
|
||||
///
|
||||
/// ```
|
||||
/// let x = 1.0f32;
|
||||
/// let y = 2.0f32;
|
||||
///
|
||||
/// assert_eq!(x.min(y), x);
|
||||
/// ```
|
||||
///
|
||||
/// If one of the arguments is NaN, then the other argument is returned.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn min(self, other: f32) -> f32 {
|
||||
Float::min(self, other)
|
||||
}
|
||||
|
||||
/// Raw transmutation to `u32`.
|
||||
///
|
||||
/// This is currently identical to `transmute::<f32, u32>(self)` on all platforms.
|
||||
///
|
||||
/// See `from_bits` for some discussion of the portability of this operation
|
||||
/// (there are almost no issues).
|
||||
///
|
||||
/// Note that this function is distinct from `as` casting, which attempts to
|
||||
/// preserve the *numeric* value, and not the bitwise value.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// assert_ne!((1f32).to_bits(), 1f32 as u32); // to_bits() is not casting!
|
||||
/// assert_eq!((12.5f32).to_bits(), 0x41480000);
|
||||
///
|
||||
/// ```
|
||||
#[stable(feature = "float_bits_conv", since = "1.20.0")]
|
||||
#[inline]
|
||||
pub fn to_bits(self) -> u32 {
|
||||
Float::to_bits(self)
|
||||
}
|
||||
|
||||
/// Raw transmutation from `u32`.
|
||||
///
|
||||
/// This is currently identical to `transmute::<u32, f32>(v)` on all platforms.
|
||||
/// It turns out this is incredibly portable, for two reasons:
|
||||
///
|
||||
/// * Floats and Ints have the same endianness on all supported platforms.
|
||||
/// * IEEE-754 very precisely specifies the bit layout of floats.
|
||||
///
|
||||
/// However there is one caveat: prior to the 2008 version of IEEE-754, how
|
||||
/// to interpret the NaN signaling bit wasn't actually specified. Most platforms
|
||||
/// (notably x86 and ARM) picked the interpretation that was ultimately
|
||||
/// standardized in 2008, but some didn't (notably MIPS). As a result, all
|
||||
/// signaling NaNs on MIPS are quiet NaNs on x86, and vice-versa.
|
||||
///
|
||||
/// Rather than trying to preserve signaling-ness cross-platform, this
|
||||
/// implementation favours preserving the exact bits. This means that
|
||||
/// any payloads encoded in NaNs will be preserved even if the result of
|
||||
/// this method is sent over the network from an x86 machine to a MIPS one.
|
||||
///
|
||||
/// If the results of this method are only manipulated by the same
|
||||
/// architecture that produced them, then there is no portability concern.
|
||||
///
|
||||
/// If the input isn't NaN, then there is no portability concern.
|
||||
///
|
||||
/// If you don't care about signalingness (very likely), then there is no
|
||||
/// portability concern.
|
||||
///
|
||||
/// Note that this function is distinct from `as` casting, which attempts to
|
||||
/// preserve the *numeric* value, and not the bitwise value.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
/// let v = f32::from_bits(0x41480000);
|
||||
/// let difference = (v - 12.5).abs();
|
||||
/// assert!(difference <= 1e-5);
|
||||
/// ```
|
||||
#[stable(feature = "float_bits_conv", since = "1.20.0")]
|
||||
#[inline]
|
||||
pub fn from_bits(v: u32) -> Self {
|
||||
Float::from_bits(v)
|
||||
}
|
||||
}}
|
||||
|
||||
#[lang = "f32"]
|
||||
#[cfg(not(test))]
|
||||
#[cfg(not(stage0))]
|
||||
impl f32 {
|
||||
f32_core_methods!();
|
||||
}
|
||||
|
|
|
@ -19,8 +19,9 @@
|
|||
|
||||
use intrinsics;
|
||||
use mem;
|
||||
use num::FpCategory as Fp;
|
||||
use num::Float;
|
||||
#[cfg(not(stage0))] use num::FpCategory;
|
||||
use num::FpCategory as Fp;
|
||||
|
||||
/// The radix or base of the internal representation of `f64`.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -291,3 +292,296 @@ impl Float for f64 {
|
|||
unsafe { mem::transmute(v) }
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: remove (inline) this macro and the Float trait
|
||||
// when updating to a bootstrap compiler that has the new lang items.
|
||||
#[cfg_attr(stage0, macro_export)]
|
||||
#[unstable(feature = "core_float", issue = "32110")]
|
||||
macro_rules! f64_core_methods { () => {
|
||||
/// Returns `true` if this value is `NaN` and false otherwise.
|
||||
///
|
||||
/// ```
|
||||
/// use std::f64;
|
||||
///
|
||||
/// let nan = f64::NAN;
|
||||
/// let f = 7.0_f64;
|
||||
///
|
||||
/// assert!(nan.is_nan());
|
||||
/// assert!(!f.is_nan());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_nan(self) -> bool { Float::is_nan(self) }
|
||||
|
||||
/// Returns `true` if this value is positive infinity or negative infinity and
|
||||
/// false otherwise.
|
||||
///
|
||||
/// ```
|
||||
/// use std::f64;
|
||||
///
|
||||
/// let f = 7.0f64;
|
||||
/// let inf = f64::INFINITY;
|
||||
/// let neg_inf = f64::NEG_INFINITY;
|
||||
/// let nan = f64::NAN;
|
||||
///
|
||||
/// assert!(!f.is_infinite());
|
||||
/// assert!(!nan.is_infinite());
|
||||
///
|
||||
/// assert!(inf.is_infinite());
|
||||
/// assert!(neg_inf.is_infinite());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_infinite(self) -> bool { Float::is_infinite(self) }
|
||||
|
||||
/// Returns `true` if this number is neither infinite nor `NaN`.
|
||||
///
|
||||
/// ```
|
||||
/// use std::f64;
|
||||
///
|
||||
/// let f = 7.0f64;
|
||||
/// let inf: f64 = f64::INFINITY;
|
||||
/// let neg_inf: f64 = f64::NEG_INFINITY;
|
||||
/// let nan: f64 = f64::NAN;
|
||||
///
|
||||
/// assert!(f.is_finite());
|
||||
///
|
||||
/// assert!(!nan.is_finite());
|
||||
/// assert!(!inf.is_finite());
|
||||
/// assert!(!neg_inf.is_finite());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_finite(self) -> bool { Float::is_finite(self) }
|
||||
|
||||
/// Returns `true` if the number is neither zero, infinite,
|
||||
/// [subnormal][subnormal], or `NaN`.
|
||||
///
|
||||
/// ```
|
||||
/// use std::f64;
|
||||
///
|
||||
/// let min = f64::MIN_POSITIVE; // 2.2250738585072014e-308f64
|
||||
/// let max = f64::MAX;
|
||||
/// let lower_than_min = 1.0e-308_f64;
|
||||
/// let zero = 0.0f64;
|
||||
///
|
||||
/// assert!(min.is_normal());
|
||||
/// assert!(max.is_normal());
|
||||
///
|
||||
/// assert!(!zero.is_normal());
|
||||
/// assert!(!f64::NAN.is_normal());
|
||||
/// assert!(!f64::INFINITY.is_normal());
|
||||
/// // Values between `0` and `min` are Subnormal.
|
||||
/// assert!(!lower_than_min.is_normal());
|
||||
/// ```
|
||||
/// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_normal(self) -> bool { Float::is_normal(self) }
|
||||
|
||||
/// 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.
|
||||
///
|
||||
/// ```
|
||||
/// use std::num::FpCategory;
|
||||
/// use std::f64;
|
||||
///
|
||||
/// let num = 12.4_f64;
|
||||
/// let inf = f64::INFINITY;
|
||||
///
|
||||
/// assert_eq!(num.classify(), FpCategory::Normal);
|
||||
/// assert_eq!(inf.classify(), FpCategory::Infinite);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn classify(self) -> FpCategory { Float::classify(self) }
|
||||
|
||||
/// Returns `true` if and only if `self` has a positive sign, including `+0.0`, `NaN`s with
|
||||
/// positive sign bit and positive infinity.
|
||||
///
|
||||
/// ```
|
||||
/// let f = 7.0_f64;
|
||||
/// let g = -7.0_f64;
|
||||
///
|
||||
/// assert!(f.is_sign_positive());
|
||||
/// assert!(!g.is_sign_positive());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_sign_positive(self) -> bool { Float::is_sign_positive(self) }
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_deprecated(since = "1.0.0", reason = "renamed to is_sign_positive")]
|
||||
#[inline]
|
||||
#[doc(hidden)]
|
||||
pub fn is_positive(self) -> bool { Float::is_sign_positive(self) }
|
||||
|
||||
/// Returns `true` if and only if `self` has a negative sign, including `-0.0`, `NaN`s with
|
||||
/// negative sign bit and negative infinity.
|
||||
///
|
||||
/// ```
|
||||
/// let f = 7.0_f64;
|
||||
/// let g = -7.0_f64;
|
||||
///
|
||||
/// assert!(!f.is_sign_negative());
|
||||
/// assert!(g.is_sign_negative());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_sign_negative(self) -> bool { Float::is_sign_negative(self) }
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_deprecated(since = "1.0.0", reason = "renamed to is_sign_negative")]
|
||||
#[inline]
|
||||
#[doc(hidden)]
|
||||
pub fn is_negative(self) -> bool { Float::is_sign_negative(self) }
|
||||
|
||||
/// Takes the reciprocal (inverse) of a number, `1/x`.
|
||||
///
|
||||
/// ```
|
||||
/// let x = 2.0_f64;
|
||||
/// let abs_difference = (x.recip() - (1.0/x)).abs();
|
||||
///
|
||||
/// assert!(abs_difference < 1e-10);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn recip(self) -> f64 { Float::recip(self) }
|
||||
|
||||
/// Converts radians to degrees.
|
||||
///
|
||||
/// ```
|
||||
/// use std::f64::consts;
|
||||
///
|
||||
/// let angle = consts::PI;
|
||||
///
|
||||
/// let abs_difference = (angle.to_degrees() - 180.0).abs();
|
||||
///
|
||||
/// assert!(abs_difference < 1e-10);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn to_degrees(self) -> f64 { Float::to_degrees(self) }
|
||||
|
||||
/// Converts degrees to radians.
|
||||
///
|
||||
/// ```
|
||||
/// use std::f64::consts;
|
||||
///
|
||||
/// let angle = 180.0_f64;
|
||||
///
|
||||
/// let abs_difference = (angle.to_radians() - consts::PI).abs();
|
||||
///
|
||||
/// assert!(abs_difference < 1e-10);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn to_radians(self) -> f64 { Float::to_radians(self) }
|
||||
|
||||
/// Returns the maximum of the two numbers.
|
||||
///
|
||||
/// ```
|
||||
/// let x = 1.0_f64;
|
||||
/// let y = 2.0_f64;
|
||||
///
|
||||
/// assert_eq!(x.max(y), y);
|
||||
/// ```
|
||||
///
|
||||
/// If one of the arguments is NaN, then the other argument is returned.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn max(self, other: f64) -> f64 {
|
||||
Float::max(self, other)
|
||||
}
|
||||
|
||||
/// Returns the minimum of the two numbers.
|
||||
///
|
||||
/// ```
|
||||
/// let x = 1.0_f64;
|
||||
/// let y = 2.0_f64;
|
||||
///
|
||||
/// assert_eq!(x.min(y), x);
|
||||
/// ```
|
||||
///
|
||||
/// If one of the arguments is NaN, then the other argument is returned.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn min(self, other: f64) -> f64 {
|
||||
Float::min(self, other)
|
||||
}
|
||||
|
||||
/// Raw transmutation to `u64`.
|
||||
///
|
||||
/// This is currently identical to `transmute::<f64, u64>(self)` on all platforms.
|
||||
///
|
||||
/// See `from_bits` for some discussion of the portability of this operation
|
||||
/// (there are almost no issues).
|
||||
///
|
||||
/// Note that this function is distinct from `as` casting, which attempts to
|
||||
/// preserve the *numeric* value, and not the bitwise value.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// assert!((1f64).to_bits() != 1f64 as u64); // to_bits() is not casting!
|
||||
/// assert_eq!((12.5f64).to_bits(), 0x4029000000000000);
|
||||
///
|
||||
/// ```
|
||||
#[stable(feature = "float_bits_conv", since = "1.20.0")]
|
||||
#[inline]
|
||||
pub fn to_bits(self) -> u64 {
|
||||
Float::to_bits(self)
|
||||
}
|
||||
|
||||
/// Raw transmutation from `u64`.
|
||||
///
|
||||
/// This is currently identical to `transmute::<u64, f64>(v)` on all platforms.
|
||||
/// It turns out this is incredibly portable, for two reasons:
|
||||
///
|
||||
/// * Floats and Ints have the same endianness on all supported platforms.
|
||||
/// * IEEE-754 very precisely specifies the bit layout of floats.
|
||||
///
|
||||
/// However there is one caveat: prior to the 2008 version of IEEE-754, how
|
||||
/// to interpret the NaN signaling bit wasn't actually specified. Most platforms
|
||||
/// (notably x86 and ARM) picked the interpretation that was ultimately
|
||||
/// standardized in 2008, but some didn't (notably MIPS). As a result, all
|
||||
/// signaling NaNs on MIPS are quiet NaNs on x86, and vice-versa.
|
||||
///
|
||||
/// Rather than trying to preserve signaling-ness cross-platform, this
|
||||
/// implementation favours preserving the exact bits. This means that
|
||||
/// any payloads encoded in NaNs will be preserved even if the result of
|
||||
/// this method is sent over the network from an x86 machine to a MIPS one.
|
||||
///
|
||||
/// If the results of this method are only manipulated by the same
|
||||
/// architecture that produced them, then there is no portability concern.
|
||||
///
|
||||
/// If the input isn't NaN, then there is no portability concern.
|
||||
///
|
||||
/// If you don't care about signalingness (very likely), then there is no
|
||||
/// portability concern.
|
||||
///
|
||||
/// Note that this function is distinct from `as` casting, which attempts to
|
||||
/// preserve the *numeric* value, and not the bitwise value.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f64;
|
||||
/// let v = f64::from_bits(0x4029000000000000);
|
||||
/// let difference = (v - 12.5).abs();
|
||||
/// assert!(difference <= 1e-5);
|
||||
/// ```
|
||||
#[stable(feature = "float_bits_conv", since = "1.20.0")]
|
||||
#[inline]
|
||||
pub fn from_bits(v: u64) -> Self {
|
||||
Float::from_bits(v)
|
||||
}
|
||||
}}
|
||||
|
||||
#[lang = "f64"]
|
||||
#[cfg(not(test))]
|
||||
#[cfg(not(stage0))]
|
||||
impl f64 {
|
||||
f64_core_methods!();
|
||||
}
|
||||
|
|
|
@ -233,6 +233,8 @@ language_item_table! {
|
|||
UsizeImplItem, "usize", usize_impl;
|
||||
F32ImplItem, "f32", f32_impl;
|
||||
F64ImplItem, "f64", f64_impl;
|
||||
F32RuntimeImplItem, "f32_runtime", f32_runtime_impl;
|
||||
F64RuntimeImplItem, "f64_runtime", f64_runtime_impl;
|
||||
|
||||
SizedTraitLangItem, "sized", sized_trait;
|
||||
UnsizeTraitLangItem, "unsize", unsize_trait;
|
||||
|
|
|
@ -547,10 +547,16 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
|||
ty::TyFloat(ast::FloatTy::F32) => {
|
||||
let lang_def_id = lang_items.f32_impl();
|
||||
self.assemble_inherent_impl_for_primitive(lang_def_id);
|
||||
|
||||
let lang_def_id = lang_items.f32_runtime_impl();
|
||||
self.assemble_inherent_impl_for_primitive(lang_def_id);
|
||||
}
|
||||
ty::TyFloat(ast::FloatTy::F64) => {
|
||||
let lang_def_id = lang_items.f64_impl();
|
||||
self.assemble_inherent_impl_for_primitive(lang_def_id);
|
||||
|
||||
let lang_def_id = lang_items.f64_runtime_impl();
|
||||
self.assemble_inherent_impl_for_primitive(lang_def_id);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
|
@ -258,7 +258,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
|
|||
ty::TyFloat(ast::FloatTy::F32) => {
|
||||
self.check_primitive_impl(def_id,
|
||||
lang_items.f32_impl(),
|
||||
None,
|
||||
lang_items.f32_runtime_impl(),
|
||||
"f32",
|
||||
"f32",
|
||||
item.span);
|
||||
|
@ -266,7 +266,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
|
|||
ty::TyFloat(ast::FloatTy::F64) => {
|
||||
self.check_primitive_impl(def_id,
|
||||
lang_items.f64_impl(),
|
||||
None,
|
||||
lang_items.f64_runtime_impl(),
|
||||
"f64",
|
||||
"f64",
|
||||
item.span);
|
||||
|
|
|
@ -286,6 +286,8 @@ pub fn build_impls(cx: &DocContext, did: DefId, auto_traits: bool) -> Vec<clean:
|
|||
lang_items.u128_impl(),
|
||||
lang_items.f32_impl(),
|
||||
lang_items.f64_impl(),
|
||||
lang_items.f32_runtime_impl(),
|
||||
lang_items.f64_runtime_impl(),
|
||||
lang_items.char_impl(),
|
||||
lang_items.str_impl(),
|
||||
lang_items.slice_impl(),
|
||||
|
|
|
@ -19,10 +19,11 @@
|
|||
#![allow(missing_docs)]
|
||||
|
||||
#[cfg(not(test))]
|
||||
use core::num;
|
||||
use core::num::Float;
|
||||
#[cfg(not(test))]
|
||||
use intrinsics;
|
||||
#[cfg(not(test))]
|
||||
#[cfg(stage0)]
|
||||
use num::FpCategory;
|
||||
#[cfg(not(test))]
|
||||
use sys::cmath;
|
||||
|
@ -39,106 +40,11 @@ pub use core::f32::{MIN, MIN_POSITIVE, MAX};
|
|||
pub use core::f32::consts;
|
||||
|
||||
#[cfg(not(test))]
|
||||
#[lang = "f32"]
|
||||
#[cfg_attr(stage0, lang = "f32")]
|
||||
#[cfg_attr(not(stage0), lang = "f32_runtime")]
|
||||
impl f32 {
|
||||
/// Returns `true` if this value is `NaN` and false otherwise.
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
/// let nan = f32::NAN;
|
||||
/// let f = 7.0_f32;
|
||||
///
|
||||
/// assert!(nan.is_nan());
|
||||
/// assert!(!f.is_nan());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_nan(self) -> bool { num::Float::is_nan(self) }
|
||||
|
||||
/// Returns `true` if this value is positive infinity or negative infinity and
|
||||
/// false otherwise.
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
/// let f = 7.0f32;
|
||||
/// let inf = f32::INFINITY;
|
||||
/// let neg_inf = f32::NEG_INFINITY;
|
||||
/// let nan = f32::NAN;
|
||||
///
|
||||
/// assert!(!f.is_infinite());
|
||||
/// assert!(!nan.is_infinite());
|
||||
///
|
||||
/// assert!(inf.is_infinite());
|
||||
/// assert!(neg_inf.is_infinite());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_infinite(self) -> bool { num::Float::is_infinite(self) }
|
||||
|
||||
/// Returns `true` if this number is neither infinite nor `NaN`.
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
/// let f = 7.0f32;
|
||||
/// let inf = f32::INFINITY;
|
||||
/// let neg_inf = f32::NEG_INFINITY;
|
||||
/// let nan = f32::NAN;
|
||||
///
|
||||
/// assert!(f.is_finite());
|
||||
///
|
||||
/// assert!(!nan.is_finite());
|
||||
/// assert!(!inf.is_finite());
|
||||
/// assert!(!neg_inf.is_finite());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_finite(self) -> bool { num::Float::is_finite(self) }
|
||||
|
||||
/// Returns `true` if the number is neither zero, infinite,
|
||||
/// [subnormal][subnormal], or `NaN`.
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
/// let min = f32::MIN_POSITIVE; // 1.17549435e-38f32
|
||||
/// let max = f32::MAX;
|
||||
/// let lower_than_min = 1.0e-40_f32;
|
||||
/// let zero = 0.0_f32;
|
||||
///
|
||||
/// assert!(min.is_normal());
|
||||
/// assert!(max.is_normal());
|
||||
///
|
||||
/// assert!(!zero.is_normal());
|
||||
/// assert!(!f32::NAN.is_normal());
|
||||
/// assert!(!f32::INFINITY.is_normal());
|
||||
/// // Values between `0` and `min` are Subnormal.
|
||||
/// assert!(!lower_than_min.is_normal());
|
||||
/// ```
|
||||
/// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_normal(self) -> bool { num::Float::is_normal(self) }
|
||||
|
||||
/// 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.
|
||||
///
|
||||
/// ```
|
||||
/// use std::num::FpCategory;
|
||||
/// use std::f32;
|
||||
///
|
||||
/// let num = 12.4_f32;
|
||||
/// let inf = f32::INFINITY;
|
||||
///
|
||||
/// assert_eq!(num.classify(), FpCategory::Normal);
|
||||
/// assert_eq!(inf.classify(), FpCategory::Infinite);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn classify(self) -> FpCategory { num::Float::classify(self) }
|
||||
#[cfg(stage0)]
|
||||
f32_core_methods!();
|
||||
|
||||
/// Returns the largest integer less than or equal to a number.
|
||||
///
|
||||
|
@ -257,7 +163,7 @@ impl f32 {
|
|||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn abs(self) -> f32 { num::Float::abs(self) }
|
||||
pub fn abs(self) -> f32 { Float::abs(self) }
|
||||
|
||||
/// Returns a number that represents the sign of `self`.
|
||||
///
|
||||
|
@ -277,35 +183,7 @@ impl f32 {
|
|||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn signum(self) -> f32 { num::Float::signum(self) }
|
||||
|
||||
/// Returns `true` if and only if `self` has a positive sign, including `+0.0`, `NaN`s with
|
||||
/// positive sign bit and positive infinity.
|
||||
///
|
||||
/// ```
|
||||
/// let f = 7.0_f32;
|
||||
/// let g = -7.0_f32;
|
||||
///
|
||||
/// assert!(f.is_sign_positive());
|
||||
/// assert!(!g.is_sign_positive());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_sign_positive(self) -> bool { num::Float::is_sign_positive(self) }
|
||||
|
||||
/// Returns `true` if and only if `self` has a negative sign, including `-0.0`, `NaN`s with
|
||||
/// negative sign bit and negative infinity.
|
||||
///
|
||||
/// ```
|
||||
/// let f = 7.0f32;
|
||||
/// let g = -7.0f32;
|
||||
///
|
||||
/// assert!(!f.is_sign_negative());
|
||||
/// assert!(g.is_sign_negative());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_sign_negative(self) -> bool { num::Float::is_sign_negative(self) }
|
||||
pub fn signum(self) -> f32 { Float::signum(self) }
|
||||
|
||||
/// Fused multiply-add. Computes `(self * a) + b` with only one rounding
|
||||
/// error. This produces a more accurate result with better performance than
|
||||
|
@ -380,20 +258,6 @@ impl f32 {
|
|||
}
|
||||
|
||||
|
||||
/// Takes the reciprocal (inverse) of a number, `1/x`.
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
///
|
||||
/// let x = 2.0_f32;
|
||||
/// let abs_difference = (x.recip() - (1.0/x)).abs();
|
||||
///
|
||||
/// assert!(abs_difference <= f32::EPSILON);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn recip(self) -> f32 { num::Float::recip(self) }
|
||||
|
||||
/// Raises a number to an integer power.
|
||||
///
|
||||
/// Using this function is generally faster than using `powf`
|
||||
|
@ -408,7 +272,7 @@ impl f32 {
|
|||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn powi(self, n: i32) -> f32 { num::Float::powi(self, n) }
|
||||
pub fn powi(self, n: i32) -> f32 { Float::powi(self, n) }
|
||||
|
||||
/// Raises a number to a floating point power.
|
||||
///
|
||||
|
@ -584,68 +448,6 @@ impl f32 {
|
|||
return unsafe { intrinsics::log10f32(self) };
|
||||
}
|
||||
|
||||
/// Converts radians to degrees.
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32::{self, consts};
|
||||
///
|
||||
/// let angle = consts::PI;
|
||||
///
|
||||
/// let abs_difference = (angle.to_degrees() - 180.0).abs();
|
||||
///
|
||||
/// assert!(abs_difference <= f32::EPSILON);
|
||||
/// ```
|
||||
#[stable(feature = "f32_deg_rad_conversions", since="1.7.0")]
|
||||
#[inline]
|
||||
pub fn to_degrees(self) -> f32 { num::Float::to_degrees(self) }
|
||||
|
||||
/// Converts degrees to radians.
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32::{self, consts};
|
||||
///
|
||||
/// let angle = 180.0f32;
|
||||
///
|
||||
/// let abs_difference = (angle.to_radians() - consts::PI).abs();
|
||||
///
|
||||
/// assert!(abs_difference <= f32::EPSILON);
|
||||
/// ```
|
||||
#[stable(feature = "f32_deg_rad_conversions", since="1.7.0")]
|
||||
#[inline]
|
||||
pub fn to_radians(self) -> f32 { num::Float::to_radians(self) }
|
||||
|
||||
/// Returns the maximum of the two numbers.
|
||||
///
|
||||
/// ```
|
||||
/// let x = 1.0f32;
|
||||
/// let y = 2.0f32;
|
||||
///
|
||||
/// assert_eq!(x.max(y), y);
|
||||
/// ```
|
||||
///
|
||||
/// If one of the arguments is NaN, then the other argument is returned.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn max(self, other: f32) -> f32 {
|
||||
num::Float::max(self, other)
|
||||
}
|
||||
|
||||
/// Returns the minimum of the two numbers.
|
||||
///
|
||||
/// ```
|
||||
/// let x = 1.0f32;
|
||||
/// let y = 2.0f32;
|
||||
///
|
||||
/// assert_eq!(x.min(y), x);
|
||||
/// ```
|
||||
///
|
||||
/// If one of the arguments is NaN, then the other argument is returned.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn min(self, other: f32) -> f32 {
|
||||
num::Float::min(self, other)
|
||||
}
|
||||
|
||||
/// The positive difference of two numbers.
|
||||
///
|
||||
/// * If `self <= other`: `0:0`
|
||||
|
@ -1046,73 +848,6 @@ impl f32 {
|
|||
pub fn atanh(self) -> f32 {
|
||||
0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
|
||||
}
|
||||
|
||||
/// Raw transmutation to `u32`.
|
||||
///
|
||||
/// This is currently identical to `transmute::<f32, u32>(self)` on all platforms.
|
||||
///
|
||||
/// See `from_bits` for some discussion of the portability of this operation
|
||||
/// (there are almost no issues).
|
||||
///
|
||||
/// Note that this function is distinct from `as` casting, which attempts to
|
||||
/// preserve the *numeric* value, and not the bitwise value.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// assert_ne!((1f32).to_bits(), 1f32 as u32); // to_bits() is not casting!
|
||||
/// assert_eq!((12.5f32).to_bits(), 0x41480000);
|
||||
///
|
||||
/// ```
|
||||
#[stable(feature = "float_bits_conv", since = "1.20.0")]
|
||||
#[inline]
|
||||
pub fn to_bits(self) -> u32 {
|
||||
num::Float::to_bits(self)
|
||||
}
|
||||
|
||||
/// Raw transmutation from `u32`.
|
||||
///
|
||||
/// This is currently identical to `transmute::<u32, f32>(v)` on all platforms.
|
||||
/// It turns out this is incredibly portable, for two reasons:
|
||||
///
|
||||
/// * Floats and Ints have the same endianness on all supported platforms.
|
||||
/// * IEEE-754 very precisely specifies the bit layout of floats.
|
||||
///
|
||||
/// However there is one caveat: prior to the 2008 version of IEEE-754, how
|
||||
/// to interpret the NaN signaling bit wasn't actually specified. Most platforms
|
||||
/// (notably x86 and ARM) picked the interpretation that was ultimately
|
||||
/// standardized in 2008, but some didn't (notably MIPS). As a result, all
|
||||
/// signaling NaNs on MIPS are quiet NaNs on x86, and vice-versa.
|
||||
///
|
||||
/// Rather than trying to preserve signaling-ness cross-platform, this
|
||||
/// implementation favours preserving the exact bits. This means that
|
||||
/// any payloads encoded in NaNs will be preserved even if the result of
|
||||
/// this method is sent over the network from an x86 machine to a MIPS one.
|
||||
///
|
||||
/// If the results of this method are only manipulated by the same
|
||||
/// architecture that produced them, then there is no portability concern.
|
||||
///
|
||||
/// If the input isn't NaN, then there is no portability concern.
|
||||
///
|
||||
/// If you don't care about signalingness (very likely), then there is no
|
||||
/// portability concern.
|
||||
///
|
||||
/// Note that this function is distinct from `as` casting, which attempts to
|
||||
/// preserve the *numeric* value, and not the bitwise value.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
/// let v = f32::from_bits(0x41480000);
|
||||
/// let difference = (v - 12.5).abs();
|
||||
/// assert!(difference <= 1e-5);
|
||||
/// ```
|
||||
#[stable(feature = "float_bits_conv", since = "1.20.0")]
|
||||
#[inline]
|
||||
pub fn from_bits(v: u32) -> Self {
|
||||
num::Float::from_bits(v)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -19,10 +19,11 @@
|
|||
#![allow(missing_docs)]
|
||||
|
||||
#[cfg(not(test))]
|
||||
use core::num;
|
||||
use core::num::Float;
|
||||
#[cfg(not(test))]
|
||||
use intrinsics;
|
||||
#[cfg(not(test))]
|
||||
#[cfg(stage0)]
|
||||
use num::FpCategory;
|
||||
#[cfg(not(test))]
|
||||
use sys::cmath;
|
||||
|
@ -39,106 +40,11 @@ pub use core::f64::{MIN, MIN_POSITIVE, MAX};
|
|||
pub use core::f64::consts;
|
||||
|
||||
#[cfg(not(test))]
|
||||
#[lang = "f64"]
|
||||
#[cfg_attr(stage0, lang = "f64")]
|
||||
#[cfg_attr(not(stage0), lang = "f64_runtime")]
|
||||
impl f64 {
|
||||
/// Returns `true` if this value is `NaN` and false otherwise.
|
||||
///
|
||||
/// ```
|
||||
/// use std::f64;
|
||||
///
|
||||
/// let nan = f64::NAN;
|
||||
/// let f = 7.0_f64;
|
||||
///
|
||||
/// assert!(nan.is_nan());
|
||||
/// assert!(!f.is_nan());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_nan(self) -> bool { num::Float::is_nan(self) }
|
||||
|
||||
/// Returns `true` if this value is positive infinity or negative infinity and
|
||||
/// false otherwise.
|
||||
///
|
||||
/// ```
|
||||
/// use std::f64;
|
||||
///
|
||||
/// let f = 7.0f64;
|
||||
/// let inf = f64::INFINITY;
|
||||
/// let neg_inf = f64::NEG_INFINITY;
|
||||
/// let nan = f64::NAN;
|
||||
///
|
||||
/// assert!(!f.is_infinite());
|
||||
/// assert!(!nan.is_infinite());
|
||||
///
|
||||
/// assert!(inf.is_infinite());
|
||||
/// assert!(neg_inf.is_infinite());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_infinite(self) -> bool { num::Float::is_infinite(self) }
|
||||
|
||||
/// Returns `true` if this number is neither infinite nor `NaN`.
|
||||
///
|
||||
/// ```
|
||||
/// use std::f64;
|
||||
///
|
||||
/// let f = 7.0f64;
|
||||
/// let inf: f64 = f64::INFINITY;
|
||||
/// let neg_inf: f64 = f64::NEG_INFINITY;
|
||||
/// let nan: f64 = f64::NAN;
|
||||
///
|
||||
/// assert!(f.is_finite());
|
||||
///
|
||||
/// assert!(!nan.is_finite());
|
||||
/// assert!(!inf.is_finite());
|
||||
/// assert!(!neg_inf.is_finite());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_finite(self) -> bool { num::Float::is_finite(self) }
|
||||
|
||||
/// Returns `true` if the number is neither zero, infinite,
|
||||
/// [subnormal][subnormal], or `NaN`.
|
||||
///
|
||||
/// ```
|
||||
/// use std::f64;
|
||||
///
|
||||
/// let min = f64::MIN_POSITIVE; // 2.2250738585072014e-308f64
|
||||
/// let max = f64::MAX;
|
||||
/// let lower_than_min = 1.0e-308_f64;
|
||||
/// let zero = 0.0f64;
|
||||
///
|
||||
/// assert!(min.is_normal());
|
||||
/// assert!(max.is_normal());
|
||||
///
|
||||
/// assert!(!zero.is_normal());
|
||||
/// assert!(!f64::NAN.is_normal());
|
||||
/// assert!(!f64::INFINITY.is_normal());
|
||||
/// // Values between `0` and `min` are Subnormal.
|
||||
/// assert!(!lower_than_min.is_normal());
|
||||
/// ```
|
||||
/// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_normal(self) -> bool { num::Float::is_normal(self) }
|
||||
|
||||
/// 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.
|
||||
///
|
||||
/// ```
|
||||
/// use std::num::FpCategory;
|
||||
/// use std::f64;
|
||||
///
|
||||
/// let num = 12.4_f64;
|
||||
/// let inf = f64::INFINITY;
|
||||
///
|
||||
/// assert_eq!(num.classify(), FpCategory::Normal);
|
||||
/// assert_eq!(inf.classify(), FpCategory::Infinite);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn classify(self) -> FpCategory { num::Float::classify(self) }
|
||||
#[cfg(stage0)]
|
||||
f64_core_methods!();
|
||||
|
||||
/// Returns the largest integer less than or equal to a number.
|
||||
///
|
||||
|
@ -235,7 +141,7 @@ impl f64 {
|
|||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn abs(self) -> f64 { num::Float::abs(self) }
|
||||
pub fn abs(self) -> f64 { Float::abs(self) }
|
||||
|
||||
/// Returns a number that represents the sign of `self`.
|
||||
///
|
||||
|
@ -255,45 +161,7 @@ impl f64 {
|
|||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn signum(self) -> f64 { num::Float::signum(self) }
|
||||
|
||||
/// Returns `true` if and only if `self` has a positive sign, including `+0.0`, `NaN`s with
|
||||
/// positive sign bit and positive infinity.
|
||||
///
|
||||
/// ```
|
||||
/// let f = 7.0_f64;
|
||||
/// let g = -7.0_f64;
|
||||
///
|
||||
/// assert!(f.is_sign_positive());
|
||||
/// assert!(!g.is_sign_positive());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_sign_positive(self) -> bool { num::Float::is_sign_positive(self) }
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_deprecated(since = "1.0.0", reason = "renamed to is_sign_positive")]
|
||||
#[inline]
|
||||
pub fn is_positive(self) -> bool { num::Float::is_sign_positive(self) }
|
||||
|
||||
/// Returns `true` if and only if `self` has a negative sign, including `-0.0`, `NaN`s with
|
||||
/// negative sign bit and negative infinity.
|
||||
///
|
||||
/// ```
|
||||
/// let f = 7.0_f64;
|
||||
/// let g = -7.0_f64;
|
||||
///
|
||||
/// assert!(!f.is_sign_negative());
|
||||
/// assert!(g.is_sign_negative());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn is_sign_negative(self) -> bool { num::Float::is_sign_negative(self) }
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_deprecated(since = "1.0.0", reason = "renamed to is_sign_negative")]
|
||||
#[inline]
|
||||
pub fn is_negative(self) -> bool { num::Float::is_sign_negative(self) }
|
||||
pub fn signum(self) -> f64 { Float::signum(self) }
|
||||
|
||||
/// Fused multiply-add. Computes `(self * a) + b` with only one rounding
|
||||
/// error. This produces a more accurate result with better performance than
|
||||
|
@ -365,18 +233,6 @@ impl f64 {
|
|||
}
|
||||
}
|
||||
|
||||
/// Takes the reciprocal (inverse) of a number, `1/x`.
|
||||
///
|
||||
/// ```
|
||||
/// let x = 2.0_f64;
|
||||
/// let abs_difference = (x.recip() - (1.0/x)).abs();
|
||||
///
|
||||
/// assert!(abs_difference < 1e-10);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn recip(self) -> f64 { num::Float::recip(self) }
|
||||
|
||||
/// Raises a number to an integer power.
|
||||
///
|
||||
/// Using this function is generally faster than using `powf`
|
||||
|
@ -389,7 +245,7 @@ impl f64 {
|
|||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn powi(self, n: i32) -> f64 { num::Float::powi(self, n) }
|
||||
pub fn powi(self, n: i32) -> f64 { Float::powi(self, n) }
|
||||
|
||||
/// Raises a number to a floating point power.
|
||||
///
|
||||
|
@ -535,68 +391,6 @@ impl f64 {
|
|||
self.log_wrapper(|n| { unsafe { intrinsics::log10f64(n) } })
|
||||
}
|
||||
|
||||
/// Converts radians to degrees.
|
||||
///
|
||||
/// ```
|
||||
/// use std::f64::consts;
|
||||
///
|
||||
/// let angle = consts::PI;
|
||||
///
|
||||
/// let abs_difference = (angle.to_degrees() - 180.0).abs();
|
||||
///
|
||||
/// assert!(abs_difference < 1e-10);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn to_degrees(self) -> f64 { num::Float::to_degrees(self) }
|
||||
|
||||
/// Converts degrees to radians.
|
||||
///
|
||||
/// ```
|
||||
/// use std::f64::consts;
|
||||
///
|
||||
/// let angle = 180.0_f64;
|
||||
///
|
||||
/// let abs_difference = (angle.to_radians() - consts::PI).abs();
|
||||
///
|
||||
/// assert!(abs_difference < 1e-10);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn to_radians(self) -> f64 { num::Float::to_radians(self) }
|
||||
|
||||
/// Returns the maximum of the two numbers.
|
||||
///
|
||||
/// ```
|
||||
/// let x = 1.0_f64;
|
||||
/// let y = 2.0_f64;
|
||||
///
|
||||
/// assert_eq!(x.max(y), y);
|
||||
/// ```
|
||||
///
|
||||
/// If one of the arguments is NaN, then the other argument is returned.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn max(self, other: f64) -> f64 {
|
||||
num::Float::max(self, other)
|
||||
}
|
||||
|
||||
/// Returns the minimum of the two numbers.
|
||||
///
|
||||
/// ```
|
||||
/// let x = 1.0_f64;
|
||||
/// let y = 2.0_f64;
|
||||
///
|
||||
/// assert_eq!(x.min(y), x);
|
||||
/// ```
|
||||
///
|
||||
/// If one of the arguments is NaN, then the other argument is returned.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn min(self, other: f64) -> f64 {
|
||||
num::Float::min(self, other)
|
||||
}
|
||||
|
||||
/// The positive difference of two numbers.
|
||||
///
|
||||
/// * If `self <= other`: `0:0`
|
||||
|
@ -1000,73 +794,6 @@ impl f64 {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Raw transmutation to `u64`.
|
||||
///
|
||||
/// This is currently identical to `transmute::<f64, u64>(self)` on all platforms.
|
||||
///
|
||||
/// See `from_bits` for some discussion of the portability of this operation
|
||||
/// (there are almost no issues).
|
||||
///
|
||||
/// Note that this function is distinct from `as` casting, which attempts to
|
||||
/// preserve the *numeric* value, and not the bitwise value.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// assert!((1f64).to_bits() != 1f64 as u64); // to_bits() is not casting!
|
||||
/// assert_eq!((12.5f64).to_bits(), 0x4029000000000000);
|
||||
///
|
||||
/// ```
|
||||
#[stable(feature = "float_bits_conv", since = "1.20.0")]
|
||||
#[inline]
|
||||
pub fn to_bits(self) -> u64 {
|
||||
num::Float::to_bits(self)
|
||||
}
|
||||
|
||||
/// Raw transmutation from `u64`.
|
||||
///
|
||||
/// This is currently identical to `transmute::<u64, f64>(v)` on all platforms.
|
||||
/// It turns out this is incredibly portable, for two reasons:
|
||||
///
|
||||
/// * Floats and Ints have the same endianness on all supported platforms.
|
||||
/// * IEEE-754 very precisely specifies the bit layout of floats.
|
||||
///
|
||||
/// However there is one caveat: prior to the 2008 version of IEEE-754, how
|
||||
/// to interpret the NaN signaling bit wasn't actually specified. Most platforms
|
||||
/// (notably x86 and ARM) picked the interpretation that was ultimately
|
||||
/// standardized in 2008, but some didn't (notably MIPS). As a result, all
|
||||
/// signaling NaNs on MIPS are quiet NaNs on x86, and vice-versa.
|
||||
///
|
||||
/// Rather than trying to preserve signaling-ness cross-platform, this
|
||||
/// implementation favours preserving the exact bits. This means that
|
||||
/// any payloads encoded in NaNs will be preserved even if the result of
|
||||
/// this method is sent over the network from an x86 machine to a MIPS one.
|
||||
///
|
||||
/// If the results of this method are only manipulated by the same
|
||||
/// architecture that produced them, then there is no portability concern.
|
||||
///
|
||||
/// If the input isn't NaN, then there is no portability concern.
|
||||
///
|
||||
/// If you don't care about signalingness (very likely), then there is no
|
||||
/// portability concern.
|
||||
///
|
||||
/// Note that this function is distinct from `as` casting, which attempts to
|
||||
/// preserve the *numeric* value, and not the bitwise value.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::f64;
|
||||
/// let v = f64::from_bits(0x4029000000000000);
|
||||
/// let difference = (v - 12.5).abs();
|
||||
/// assert!(difference <= 1e-5);
|
||||
/// ```
|
||||
#[stable(feature = "float_bits_conv", since = "1.20.0")]
|
||||
#[inline]
|
||||
pub fn from_bits(v: u64) -> Self {
|
||||
num::Float::from_bits(v)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue