auto merge of #6463 : bjz/rust/numeric-traits, r=thestinger
This is part of the numeric trait reform tracked on issue #4819
This commit is contained in:
commit
84745b483f
@ -10,6 +10,7 @@
|
||||
|
||||
//! Operations and constants for `f32`
|
||||
|
||||
use libc::c_int;
|
||||
use num::{Zero, One, strconv};
|
||||
use num::{FPCategory, FPNaN, FPInfinite , FPZero, FPSubnormal, FPNormal};
|
||||
use prelude::*;
|
||||
@ -450,6 +451,57 @@ impl Hyperbolic for f32 {
|
||||
|
||||
#[inline(always)]
|
||||
fn tanh(&self) -> f32 { tanh(*self) }
|
||||
|
||||
///
|
||||
/// Inverse hyperbolic sine
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// - on success, the inverse hyperbolic sine of `self` will be returned
|
||||
/// - `self` if `self` is `0.0`, `-0.0`, `infinity`, or `neg_infinity`
|
||||
/// - `NaN` if `self` is `NaN`
|
||||
///
|
||||
#[inline(always)]
|
||||
fn asinh(&self) -> f32 {
|
||||
match *self {
|
||||
neg_infinity => neg_infinity,
|
||||
x => (x + ((x * x) + 1.0).sqrt()).ln(),
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Inverse hyperbolic cosine
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// - on success, the inverse hyperbolic cosine of `self` will be returned
|
||||
/// - `infinity` if `self` is `infinity`
|
||||
/// - `NaN` if `self` is `NaN` or `self < 1.0` (including `neg_infinity`)
|
||||
///
|
||||
#[inline(always)]
|
||||
fn acosh(&self) -> f32 {
|
||||
match *self {
|
||||
x if x < 1.0 => Float::NaN(),
|
||||
x => (x + ((x * x) - 1.0).sqrt()).ln(),
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Inverse hyperbolic tangent
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// - on success, the inverse hyperbolic tangent of `self` will be returned
|
||||
/// - `self` if `self` is `0.0` or `-0.0`
|
||||
/// - `infinity` if `self` is `1.0`
|
||||
/// - `neg_infinity` if `self` is `-1.0`
|
||||
/// - `NaN` if the `self` is `NaN` or outside the domain of `-1.0 <= self <= 1.0`
|
||||
/// (including `infinity` and `neg_infinity`)
|
||||
///
|
||||
#[inline(always)]
|
||||
fn atanh(&self) -> f32 {
|
||||
0.5 * ((2.0 * *self) / (1.0 - *self)).ln_1p()
|
||||
}
|
||||
}
|
||||
|
||||
impl Real for f32 {
|
||||
@ -620,6 +672,25 @@ impl Float for f32 {
|
||||
#[inline(always)]
|
||||
fn max_10_exp() -> int { 38 }
|
||||
|
||||
/// Constructs a floating point number by multiplying `x` by 2 raised to the power of `exp`
|
||||
#[inline(always)]
|
||||
fn ldexp(x: f32, exp: int) -> f32 {
|
||||
ldexp(x, exp as c_int)
|
||||
}
|
||||
|
||||
///
|
||||
/// Breaks the number into a normalized fraction and a base-2 exponent, satisfying:
|
||||
///
|
||||
/// - `self = x * pow(2, exp)`
|
||||
/// - `0.5 <= abs(x) < 1.0`
|
||||
///
|
||||
#[inline(always)]
|
||||
fn frexp(&self) -> (f32, int) {
|
||||
let mut exp = 0;
|
||||
let x = frexp(*self, &mut exp);
|
||||
(x, exp as int)
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns the exponential of the number, minus `1`, in a way that is accurate
|
||||
/// even if the number is close to zero
|
||||
@ -972,6 +1043,43 @@ mod tests {
|
||||
assert_approx_eq!((-1.7f32).fract(), -0.7f32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_asinh() {
|
||||
assert_eq!(0.0f32.asinh(), 0.0f32);
|
||||
assert_eq!((-0.0f32).asinh(), -0.0f32);
|
||||
assert_eq!(Float::infinity::<f32>().asinh(), Float::infinity::<f32>());
|
||||
assert_eq!(Float::neg_infinity::<f32>().asinh(), Float::neg_infinity::<f32>());
|
||||
assert!(Float::NaN::<f32>().asinh().is_NaN());
|
||||
assert_approx_eq!(2.0f32.asinh(), 1.443635475178810342493276740273105f32);
|
||||
assert_approx_eq!((-2.0f32).asinh(), -1.443635475178810342493276740273105f32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_acosh() {
|
||||
assert_eq!(1.0f32.acosh(), 0.0f32);
|
||||
assert!(0.999f32.acosh().is_NaN());
|
||||
assert_eq!(Float::infinity::<f32>().acosh(), Float::infinity::<f32>());
|
||||
assert!(Float::neg_infinity::<f32>().acosh().is_NaN());
|
||||
assert!(Float::NaN::<f32>().acosh().is_NaN());
|
||||
assert_approx_eq!(2.0f32.acosh(), 1.31695789692481670862504634730796844f32);
|
||||
assert_approx_eq!(3.0f32.acosh(), 1.76274717403908605046521864995958461f32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_atanh() {
|
||||
assert_eq!(0.0f32.atanh(), 0.0f32);
|
||||
assert_eq!((-0.0f32).atanh(), -0.0f32);
|
||||
assert_eq!(1.0f32.atanh(), Float::infinity::<f32>());
|
||||
assert_eq!((-1.0f32).atanh(), Float::neg_infinity::<f32>());
|
||||
assert!(2f64.atanh().atanh().is_NaN());
|
||||
assert!((-2f64).atanh().atanh().is_NaN());
|
||||
assert!(Float::infinity::<f64>().atanh().is_NaN());
|
||||
assert!(Float::neg_infinity::<f64>().atanh().is_NaN());
|
||||
assert!(Float::NaN::<f32>().atanh().is_NaN());
|
||||
assert_approx_eq!(0.5f32.atanh(), 0.54930614433405484569762261846126285f32);
|
||||
assert_approx_eq!((-0.5f32).atanh(), -0.54930614433405484569762261846126285f32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_real_consts() {
|
||||
assert_approx_eq!(Real::two_pi::<f32>(), 2f32 * Real::pi::<f32>());
|
||||
@ -1091,4 +1199,44 @@ mod tests {
|
||||
assert_eq!(1e-37f32.classify(), FPNormal);
|
||||
assert_eq!(1e-38f32.classify(), FPSubnormal);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ldexp() {
|
||||
// We have to use from_str until base-2 exponents
|
||||
// are supported in floating-point literals
|
||||
let f1: f32 = from_str_hex("1p-123").unwrap();
|
||||
let f2: f32 = from_str_hex("1p-111").unwrap();
|
||||
assert_eq!(Float::ldexp(1f32, -123), f1);
|
||||
assert_eq!(Float::ldexp(1f32, -111), f2);
|
||||
|
||||
assert_eq!(Float::ldexp(0f32, -123), 0f32);
|
||||
assert_eq!(Float::ldexp(-0f32, -123), -0f32);
|
||||
assert_eq!(Float::ldexp(Float::infinity::<f32>(), -123),
|
||||
Float::infinity::<f32>());
|
||||
assert_eq!(Float::ldexp(Float::neg_infinity::<f32>(), -123),
|
||||
Float::neg_infinity::<f32>());
|
||||
assert!(Float::ldexp(Float::NaN::<f32>(), -123).is_NaN());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_frexp() {
|
||||
// We have to use from_str until base-2 exponents
|
||||
// are supported in floating-point literals
|
||||
let f1: f32 = from_str_hex("1p-123").unwrap();
|
||||
let f2: f32 = from_str_hex("1p-111").unwrap();
|
||||
let (x1, exp1) = f1.frexp();
|
||||
let (x2, exp2) = f2.frexp();
|
||||
assert_eq!((x1, exp1), (0.5f32, -122));
|
||||
assert_eq!((x2, exp2), (0.5f32, -110));
|
||||
assert_eq!(Float::ldexp(x1, exp1), f1);
|
||||
assert_eq!(Float::ldexp(x2, exp2), f2);
|
||||
|
||||
assert_eq!(0f32.frexp(), (0f32, 0));
|
||||
assert_eq!((-0f32).frexp(), (-0f32, 0));
|
||||
assert_eq!(match Float::infinity::<f32>().frexp() { (x, _) => x },
|
||||
Float::infinity::<f32>())
|
||||
assert_eq!(match Float::neg_infinity::<f32>().frexp() { (x, _) => x },
|
||||
Float::neg_infinity::<f32>())
|
||||
assert!(match Float::NaN::<f32>().frexp() { (x, _) => x.is_NaN() })
|
||||
}
|
||||
}
|
||||
|
@ -463,6 +463,57 @@ impl Hyperbolic for f64 {
|
||||
|
||||
#[inline(always)]
|
||||
fn tanh(&self) -> f64 { tanh(*self) }
|
||||
|
||||
///
|
||||
/// Inverse hyperbolic sine
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// - on success, the inverse hyperbolic sine of `self` will be returned
|
||||
/// - `self` if `self` is `0.0`, `-0.0`, `infinity`, or `neg_infinity`
|
||||
/// - `NaN` if `self` is `NaN`
|
||||
///
|
||||
#[inline(always)]
|
||||
fn asinh(&self) -> f64 {
|
||||
match *self {
|
||||
neg_infinity => neg_infinity,
|
||||
x => (x + ((x * x) + 1.0).sqrt()).ln(),
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Inverse hyperbolic cosine
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// - on success, the inverse hyperbolic cosine of `self` will be returned
|
||||
/// - `infinity` if `self` is `infinity`
|
||||
/// - `NaN` if `self` is `NaN` or `self < 1.0` (including `neg_infinity`)
|
||||
///
|
||||
#[inline(always)]
|
||||
fn acosh(&self) -> f64 {
|
||||
match *self {
|
||||
x if x < 1.0 => Float::NaN(),
|
||||
x => (x + ((x * x) - 1.0).sqrt()).ln(),
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Inverse hyperbolic tangent
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// - on success, the inverse hyperbolic tangent of `self` will be returned
|
||||
/// - `self` if `self` is `0.0` or `-0.0`
|
||||
/// - `infinity` if `self` is `1.0`
|
||||
/// - `neg_infinity` if `self` is `-1.0`
|
||||
/// - `NaN` if the `self` is `NaN` or outside the domain of `-1.0 <= self <= 1.0`
|
||||
/// (including `infinity` and `neg_infinity`)
|
||||
///
|
||||
#[inline(always)]
|
||||
fn atanh(&self) -> f64 {
|
||||
0.5 * ((2.0 * *self) / (1.0 - *self)).ln_1p()
|
||||
}
|
||||
}
|
||||
|
||||
impl Real for f64 {
|
||||
@ -663,6 +714,25 @@ impl Float for f64 {
|
||||
#[inline(always)]
|
||||
fn max_10_exp() -> int { 308 }
|
||||
|
||||
/// Constructs a floating point number by multiplying `x` by 2 raised to the power of `exp`
|
||||
#[inline(always)]
|
||||
fn ldexp(x: f64, exp: int) -> f64 {
|
||||
ldexp(x, exp as c_int)
|
||||
}
|
||||
|
||||
///
|
||||
/// Breaks the number into a normalized fraction and a base-2 exponent, satisfying:
|
||||
///
|
||||
/// - `self = x * pow(2, exp)`
|
||||
/// - `0.5 <= abs(x) < 1.0`
|
||||
///
|
||||
#[inline(always)]
|
||||
fn frexp(&self) -> (f64, int) {
|
||||
let mut exp = 0;
|
||||
let x = frexp(*self, &mut exp);
|
||||
(x, exp as int)
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns the exponential of the number, minus `1`, in a way that is accurate
|
||||
/// even if the number is close to zero
|
||||
@ -1019,6 +1089,43 @@ mod tests {
|
||||
assert_approx_eq!((-1.7f64).fract(), -0.7f64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_asinh() {
|
||||
assert_eq!(0.0f64.asinh(), 0.0f64);
|
||||
assert_eq!((-0.0f64).asinh(), -0.0f64);
|
||||
assert_eq!(Float::infinity::<f64>().asinh(), Float::infinity::<f64>());
|
||||
assert_eq!(Float::neg_infinity::<f64>().asinh(), Float::neg_infinity::<f64>());
|
||||
assert!(Float::NaN::<f64>().asinh().is_NaN());
|
||||
assert_approx_eq!(2.0f64.asinh(), 1.443635475178810342493276740273105f64);
|
||||
assert_approx_eq!((-2.0f64).asinh(), -1.443635475178810342493276740273105f64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_acosh() {
|
||||
assert_eq!(1.0f64.acosh(), 0.0f64);
|
||||
assert!(0.999f64.acosh().is_NaN());
|
||||
assert_eq!(Float::infinity::<f64>().acosh(), Float::infinity::<f64>());
|
||||
assert!(Float::neg_infinity::<f64>().acosh().is_NaN());
|
||||
assert!(Float::NaN::<f64>().acosh().is_NaN());
|
||||
assert_approx_eq!(2.0f64.acosh(), 1.31695789692481670862504634730796844f64);
|
||||
assert_approx_eq!(3.0f64.acosh(), 1.76274717403908605046521864995958461f64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_atanh() {
|
||||
assert_eq!(0.0f64.atanh(), 0.0f64);
|
||||
assert_eq!((-0.0f64).atanh(), -0.0f64);
|
||||
assert_eq!(1.0f64.atanh(), Float::infinity::<f64>());
|
||||
assert_eq!((-1.0f64).atanh(), Float::neg_infinity::<f64>());
|
||||
assert!(2f64.atanh().atanh().is_NaN());
|
||||
assert!((-2f64).atanh().atanh().is_NaN());
|
||||
assert!(Float::infinity::<f64>().atanh().is_NaN());
|
||||
assert!(Float::neg_infinity::<f64>().atanh().is_NaN());
|
||||
assert!(Float::NaN::<f64>().atanh().is_NaN());
|
||||
assert_approx_eq!(0.5f64.atanh(), 0.54930614433405484569762261846126285f64);
|
||||
assert_approx_eq!((-0.5f64).atanh(), -0.54930614433405484569762261846126285f64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_real_consts() {
|
||||
assert_approx_eq!(Real::two_pi::<f64>(), 2.0 * Real::pi::<f64>());
|
||||
@ -1137,4 +1244,44 @@ mod tests {
|
||||
assert_eq!(1e-307f64.classify(), FPNormal);
|
||||
assert_eq!(1e-308f64.classify(), FPSubnormal);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ldexp() {
|
||||
// We have to use from_str until base-2 exponents
|
||||
// are supported in floating-point literals
|
||||
let f1: f64 = from_str_hex("1p-123").unwrap();
|
||||
let f2: f64 = from_str_hex("1p-111").unwrap();
|
||||
assert_eq!(Float::ldexp(1f64, -123), f1);
|
||||
assert_eq!(Float::ldexp(1f64, -111), f2);
|
||||
|
||||
assert_eq!(Float::ldexp(0f64, -123), 0f64);
|
||||
assert_eq!(Float::ldexp(-0f64, -123), -0f64);
|
||||
assert_eq!(Float::ldexp(Float::infinity::<f64>(), -123),
|
||||
Float::infinity::<f64>());
|
||||
assert_eq!(Float::ldexp(Float::neg_infinity::<f64>(), -123),
|
||||
Float::neg_infinity::<f64>());
|
||||
assert!(Float::ldexp(Float::NaN::<f64>(), -123).is_NaN());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_frexp() {
|
||||
// We have to use from_str until base-2 exponents
|
||||
// are supported in floating-point literals
|
||||
let f1: f64 = from_str_hex("1p-123").unwrap();
|
||||
let f2: f64 = from_str_hex("1p-111").unwrap();
|
||||
let (x1, exp1) = f1.frexp();
|
||||
let (x2, exp2) = f2.frexp();
|
||||
assert_eq!((x1, exp1), (0.5f64, -122));
|
||||
assert_eq!((x2, exp2), (0.5f64, -110));
|
||||
assert_eq!(Float::ldexp(x1, exp1), f1);
|
||||
assert_eq!(Float::ldexp(x2, exp2), f2);
|
||||
|
||||
assert_eq!(0f64.frexp(), (0f64, 0));
|
||||
assert_eq!((-0f64).frexp(), (-0f64, 0));
|
||||
assert_eq!(match Float::infinity::<f64>().frexp() { (x, _) => x },
|
||||
Float::infinity::<f64>())
|
||||
assert_eq!(match Float::neg_infinity::<f64>().frexp() { (x, _) => x },
|
||||
Float::neg_infinity::<f64>())
|
||||
assert!(match Float::NaN::<f64>().frexp() { (x, _) => x.is_NaN() })
|
||||
}
|
||||
}
|
||||
|
@ -585,6 +585,51 @@ impl Hyperbolic for float {
|
||||
fn tanh(&self) -> float {
|
||||
(*self as f64).tanh() as float
|
||||
}
|
||||
|
||||
///
|
||||
/// Inverse hyperbolic sine
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// - on success, the inverse hyperbolic sine of `self` will be returned
|
||||
/// - `self` if `self` is `0.0`, `-0.0`, `infinity`, or `neg_infinity`
|
||||
/// - `NaN` if `self` is `NaN`
|
||||
///
|
||||
#[inline(always)]
|
||||
fn asinh(&self) -> float {
|
||||
(*self as f64).asinh() as float
|
||||
}
|
||||
|
||||
///
|
||||
/// Inverse hyperbolic cosine
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// - on success, the inverse hyperbolic cosine of `self` will be returned
|
||||
/// - `infinity` if `self` is `infinity`
|
||||
/// - `NaN` if `self` is `NaN` or `self < 1.0` (including `neg_infinity`)
|
||||
///
|
||||
#[inline(always)]
|
||||
fn acosh(&self) -> float {
|
||||
(*self as f64).acosh() as float
|
||||
}
|
||||
|
||||
///
|
||||
/// Inverse hyperbolic tangent
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// - on success, the inverse hyperbolic tangent of `self` will be returned
|
||||
/// - `self` if `self` is `0.0` or `-0.0`
|
||||
/// - `infinity` if `self` is `1.0`
|
||||
/// - `neg_infinity` if `self` is `-1.0`
|
||||
/// - `NaN` if the `self` is `NaN` or outside the domain of `-1.0 <= self <= 1.0`
|
||||
/// (including `infinity` and `neg_infinity`)
|
||||
///
|
||||
#[inline(always)]
|
||||
fn atanh(&self) -> float {
|
||||
(*self as f64).atanh() as float
|
||||
}
|
||||
}
|
||||
|
||||
impl Real for float {
|
||||
@ -836,6 +881,25 @@ impl Float for float {
|
||||
#[inline(always)]
|
||||
fn max_10_exp() -> int { Float::max_10_exp::<f64>() }
|
||||
|
||||
/// Constructs a floating point number by multiplying `x` by 2 raised to the power of `exp`
|
||||
#[inline(always)]
|
||||
fn ldexp(x: float, exp: int) -> float {
|
||||
Float::ldexp(x as f64, exp) as float
|
||||
}
|
||||
|
||||
///
|
||||
/// Breaks the number into a normalized fraction and a base-2 exponent, satisfying:
|
||||
///
|
||||
/// - `self = x * pow(2, exp)`
|
||||
/// - `0.5 <= abs(x) < 1.0`
|
||||
///
|
||||
#[inline(always)]
|
||||
fn frexp(&self) -> (float, int) {
|
||||
match (*self as f64).frexp() {
|
||||
(x, exp) => (x as float, exp)
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns the exponential of the number, minus `1`, in a way that is accurate
|
||||
/// even if the number is close to zero
|
||||
@ -850,7 +914,9 @@ impl Float for float {
|
||||
/// than if the operations were performed separately
|
||||
///
|
||||
#[inline(always)]
|
||||
fn ln_1p(&self) -> float { (*self as f64).ln_1p() as float }
|
||||
fn ln_1p(&self) -> float {
|
||||
(*self as f64).ln_1p() as float
|
||||
}
|
||||
|
||||
///
|
||||
/// Fused multiply-add. Computes `(self * a) + b` with only one rounding error. This
|
||||
@ -972,6 +1038,43 @@ mod tests {
|
||||
assert_approx_eq!((-1.7f).fract(), -0.7f);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_asinh() {
|
||||
assert_eq!(0.0f.asinh(), 0.0f);
|
||||
assert_eq!((-0.0f).asinh(), -0.0f);
|
||||
assert_eq!(Float::infinity::<float>().asinh(), Float::infinity::<float>());
|
||||
assert_eq!(Float::neg_infinity::<float>().asinh(), Float::neg_infinity::<float>());
|
||||
assert!(Float::NaN::<float>().asinh().is_NaN());
|
||||
assert_approx_eq!(2.0f.asinh(), 1.443635475178810342493276740273105f);
|
||||
assert_approx_eq!((-2.0f).asinh(), -1.443635475178810342493276740273105f);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_acosh() {
|
||||
assert_eq!(1.0f.acosh(), 0.0f);
|
||||
assert!(0.999f.acosh().is_NaN());
|
||||
assert_eq!(Float::infinity::<float>().acosh(), Float::infinity::<float>());
|
||||
assert!(Float::neg_infinity::<float>().acosh().is_NaN());
|
||||
assert!(Float::NaN::<float>().acosh().is_NaN());
|
||||
assert_approx_eq!(2.0f.acosh(), 1.31695789692481670862504634730796844f);
|
||||
assert_approx_eq!(3.0f.acosh(), 1.76274717403908605046521864995958461f);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_atanh() {
|
||||
assert_eq!(0.0f.atanh(), 0.0f);
|
||||
assert_eq!((-0.0f).atanh(), -0.0f);
|
||||
assert_eq!(1.0f.atanh(), Float::infinity::<float>());
|
||||
assert_eq!((-1.0f).atanh(), Float::neg_infinity::<float>());
|
||||
assert!(2f64.atanh().atanh().is_NaN());
|
||||
assert!((-2f64).atanh().atanh().is_NaN());
|
||||
assert!(Float::infinity::<f64>().atanh().is_NaN());
|
||||
assert!(Float::neg_infinity::<f64>().atanh().is_NaN());
|
||||
assert!(Float::NaN::<float>().atanh().is_NaN());
|
||||
assert_approx_eq!(0.5f.atanh(), 0.54930614433405484569762261846126285f);
|
||||
assert_approx_eq!((-0.5f).atanh(), -0.54930614433405484569762261846126285f);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_real_consts() {
|
||||
assert_approx_eq!(Real::two_pi::<float>(), 2f * Real::pi::<float>());
|
||||
@ -1092,6 +1195,46 @@ mod tests {
|
||||
assert_eq!(1e-308f.classify(), FPSubnormal);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ldexp() {
|
||||
// We have to use from_str until base-2 exponents
|
||||
// are supported in floating-point literals
|
||||
let f1: float = from_str_hex("1p-123").unwrap();
|
||||
let f2: float = from_str_hex("1p-111").unwrap();
|
||||
assert_eq!(Float::ldexp(1f, -123), f1);
|
||||
assert_eq!(Float::ldexp(1f, -111), f2);
|
||||
|
||||
assert_eq!(Float::ldexp(0f, -123), 0f);
|
||||
assert_eq!(Float::ldexp(-0f, -123), -0f);
|
||||
assert_eq!(Float::ldexp(Float::infinity::<float>(), -123),
|
||||
Float::infinity::<float>());
|
||||
assert_eq!(Float::ldexp(Float::neg_infinity::<float>(), -123),
|
||||
Float::neg_infinity::<float>());
|
||||
assert!(Float::ldexp(Float::NaN::<float>(), -123).is_NaN());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_frexp() {
|
||||
// We have to use from_str until base-2 exponents
|
||||
// are supported in floating-point literals
|
||||
let f1: float = from_str_hex("1p-123").unwrap();
|
||||
let f2: float = from_str_hex("1p-111").unwrap();
|
||||
let (x1, exp1) = f1.frexp();
|
||||
let (x2, exp2) = f2.frexp();
|
||||
assert_eq!((x1, exp1), (0.5f, -122));
|
||||
assert_eq!((x2, exp2), (0.5f, -110));
|
||||
assert_eq!(Float::ldexp(x1, exp1), f1);
|
||||
assert_eq!(Float::ldexp(x2, exp2), f2);
|
||||
|
||||
assert_eq!(0f.frexp(), (0f, 0));
|
||||
assert_eq!((-0f).frexp(), (-0f, 0));
|
||||
assert_eq!(match Float::infinity::<float>().frexp() { (x, _) => x },
|
||||
Float::infinity::<float>())
|
||||
assert_eq!(match Float::neg_infinity::<float>().frexp() { (x, _) => x },
|
||||
Float::neg_infinity::<float>())
|
||||
assert!(match Float::NaN::<float>().frexp() { (x, _) => x.is_NaN() })
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_to_str_exact_do_decimal() {
|
||||
let s = to_str_exact(5.0, 4u);
|
||||
|
@ -133,6 +133,9 @@ pub trait Hyperbolic: Exponential {
|
||||
fn sinh(&self) -> Self;
|
||||
fn cosh(&self) -> Self;
|
||||
fn tanh(&self) -> Self;
|
||||
fn asinh(&self) -> Self;
|
||||
fn acosh(&self) -> Self;
|
||||
fn atanh(&self) -> Self;
|
||||
}
|
||||
|
||||
///
|
||||
@ -281,6 +284,9 @@ pub trait Float: Real
|
||||
fn min_10_exp() -> int;
|
||||
fn max_10_exp() -> int;
|
||||
|
||||
fn ldexp(x: Self, exp: int) -> Self;
|
||||
fn frexp(&self) -> (Self, int);
|
||||
|
||||
fn exp_m1(&self) -> Self;
|
||||
fn ln_1p(&self) -> Self;
|
||||
fn mul_add(&self, a: Self, b: Self) -> Self;
|
||||
|
Loading…
x
Reference in New Issue
Block a user