#![stable(feature = "rust1", since = "1.0.0")]
#![allow(missing_docs)]
+#[cfg(not(test))]
use core::num;
+#[cfg(not(test))]
use intrinsics;
+#[cfg(not(test))]
use libc::c_int;
-use num::{FpCategory, ParseFloatError};
+#[cfg(not(test))]
+use num::FpCategory;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::f64::{RADIX, MANTISSA_DIGITS, DIGITS, EPSILON};
#[cfg(not(test))]
#[lang = "f64"]
impl f64 {
- /// Parses a float as with a given radix
- #[unstable(feature = "float_from_str_radix", reason = "recently moved API",
- issue = "27736")]
- #[rustc_deprecated(since = "1.4.0",
- reason = "unclear how useful or correct this is")]
- #[allow(deprecated)]
- pub fn from_str_radix(s: &str, radix: u32) -> Result<f64, ParseFloatError> {
- num::Float::from_str_radix(s, radix)
- }
-
/// Returns `true` if this value is `NaN` and false otherwise.
///
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn ln(self) -> f64 {
- unsafe { intrinsics::logf64(self) }
+ self.log_wrapper(|n| { unsafe { intrinsics::logf64(n) } })
}
/// Returns the logarithm of the number with respect to an arbitrary base.
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn log2(self) -> f64 {
- unsafe { intrinsics::log2f64(self) }
+ self.log_wrapper(|n| { unsafe { intrinsics::log2f64(n) } })
}
/// Returns the base 10 logarithm of the number.
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn log10(self) -> f64 {
- unsafe { intrinsics::log10f64(self) }
+ self.log_wrapper(|n| { unsafe { intrinsics::log10f64(n) } })
}
/// Converts radians to degrees.
pub fn atanh(self) -> f64 {
0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
}
+
+ // Solaris/Illumos requires a wrapper around log, log2, and log10 functions
+ // because of their non-standard behavior (e.g. log(-n) returns -Inf instead
+ // of expected NaN).
+ fn log_wrapper<F: Fn(f64) -> f64>(self, log_fn: F) -> f64 {
+ if !cfg!(target_os = "solaris") {
+ log_fn(self)
+ } else {
+ if self.is_finite() {
+ if self > 0.0 {
+ log_fn(self)
+ } else if self == 0.0 {
+ NEG_INFINITY // log(0) = -Inf
+ } else {
+ NAN // log(-n) = NaN
+ }
+ } else if self.is_nan() {
+ self // log(NaN) = NaN
+ } else if self > 0.0 {
+ self // log(Inf) = Inf
+ } else {
+ NAN // log(-Inf) = NaN
+ }
+ }
+ }
}
#[cfg(test)]
#[test]
fn test_ldexp() {
- // We have to use from_str until base-2 exponents
- // are supported in floating-point literals
- let f1: f64 = f64::from_str_radix("1p-123", 16).unwrap();
- let f2: f64 = f64::from_str_radix("1p-111", 16).unwrap();
- let f3: f64 = f64::from_str_radix("1.Cp-12", 16).unwrap();
+ let f1 = 2.0f64.powi(-123);
+ let f2 = 2.0f64.powi(-111);
+ let f3 = 1.75 * 2.0f64.powi(-12);
assert_eq!(f64::ldexp(1f64, -123), f1);
assert_eq!(f64::ldexp(1f64, -111), f2);
assert_eq!(f64::ldexp(1.75f64, -12), f3);
#[test]
fn test_frexp() {
- // We have to use from_str until base-2 exponents
- // are supported in floating-point literals
- let f1: f64 = f64::from_str_radix("1p-123", 16).unwrap();
- let f2: f64 = f64::from_str_radix("1p-111", 16).unwrap();
- let f3: f64 = f64::from_str_radix("1.Cp-123", 16).unwrap();
+ let f1 = 2.0f64.powi(-123);
+ let f2 = 2.0f64.powi(-111);
+ let f3 = 1.75 * 2.0f64.powi(-123);
let (x1, exp1) = f1.frexp();
let (x2, exp2) = f2.frexp();
let (x3, exp3) = f3.frexp();