Both expm1 and ln1p have been renamed to exp_m1 and ln_1p in order to be consistent with the underscore usage elsewhere.
The exp_m1 method is used for increased accuracy when doing floating point calculations, so this has been moved from the more general 'Exponential' trait into 'Float'.
unsafe fn erf(n: c_double) -> c_double;
unsafe fn erfc(n: c_double) -> c_double;
unsafe fn exp(n: c_double) -> c_double;
- unsafe fn expm1(n: c_double) -> c_double;
+ // rename: for consistency with underscore usage elsewhere
+ #[link_name="expm1"] unsafe fn exp_m1(n: c_double) -> c_double;
unsafe fn exp2(n: c_double) -> c_double;
#[link_name="fabs"] unsafe fn abs(n: c_double) -> c_double;
// rename: for clarity and consistency with add/sub/mul/div
// renamed: "logb" /often/ is confused for log2 by beginners
#[link_name="logb"] unsafe fn log_radix(n: c_double) -> c_double;
// renamed: to be consitent with log as ln
- #[link_name="log1p"] unsafe fn ln1p(n: c_double) -> c_double;
+ #[link_name="log1p"] unsafe fn ln_1p(n: c_double) -> c_double;
unsafe fn log10(n: c_double) -> c_double;
unsafe fn log2(n: c_double) -> c_double;
#[link_name="ilogb"] unsafe fn ilog_radix(n: c_double) -> c_int;
#[link_name="erff"] unsafe fn erf(n: c_float) -> c_float;
#[link_name="erfcf"] unsafe fn erfc(n: c_float) -> c_float;
#[link_name="expf"] unsafe fn exp(n: c_float) -> c_float;
- #[link_name="expm1f"]unsafe fn expm1(n: c_float) -> c_float;
+ #[link_name="expm1f"]unsafe fn exp_m1(n: c_float) -> c_float;
#[link_name="exp2f"] unsafe fn exp2(n: c_float) -> c_float;
#[link_name="fabsf"] unsafe fn abs(n: c_float) -> c_float;
#[link_name="fdimf"]
#[link_name="logf"] unsafe fn ln(n: c_float) -> c_float;
#[link_name="logbf"] unsafe fn log_radix(n: c_float) -> c_float;
- #[link_name="log1pf"] unsafe fn ln1p(n: c_float) -> c_float;
+ #[link_name="log1pf"] unsafe fn ln_1p(n: c_float) -> c_float;
#[link_name="log2f"] unsafe fn log2(n: c_float) -> c_float;
#[link_name="log10f"] unsafe fn log10(n: c_float) -> c_float;
#[link_name="ilogbf"] unsafe fn ilog_radix(n: c_float) -> c_int;
fn cosh(n: c_float) -> c_float = c_float_utils::cosh,
fn erf(n: c_float) -> c_float = c_float_utils::erf,
fn erfc(n: c_float) -> c_float = c_float_utils::erfc,
- fn expm1(n: c_float) -> c_float = c_float_utils::expm1,
+ fn exp_m1(n: c_float) -> c_float = c_float_utils::exp_m1,
fn abs_sub(a: c_float, b: c_float) -> c_float = c_float_utils::abs_sub,
fn fmax(a: c_float, b: c_float) -> c_float = c_float_utils::fmax,
fn fmin(a: c_float, b: c_float) -> c_float = c_float_utils::fmin,
fn ldexp(x: c_float, n: c_int) -> c_float = c_float_utils::ldexp,
fn lgamma(n: c_float, sign: &mut c_int) -> c_float = c_float_utils::lgamma,
fn log_radix(n: c_float) -> c_float = c_float_utils::log_radix,
- fn ln1p(n: c_float) -> c_float = c_float_utils::ln1p,
+ fn ln_1p(n: c_float) -> c_float = c_float_utils::ln_1p,
fn ilog_radix(n: c_float) -> c_int = c_float_utils::ilog_radix,
fn modf(n: c_float, iptr: &mut c_float) -> c_float = c_float_utils::modf,
fn round(n: c_float) -> c_float = c_float_utils::round,
}
impl Exponential for f32 {
+ /// Returns the exponential of the number
#[inline(always)]
fn exp(&self) -> f32 { exp(*self) }
+ /// Returns 2 raised to the power of the number
#[inline(always)]
fn exp2(&self) -> f32 { exp2(*self) }
- #[inline(always)]
- fn expm1(&self) -> f32 { expm1(*self) }
-
/// Returns the natural logarithm of the number
#[inline(always)]
fn ln(&self) -> f32 { ln(*self) }
!(self.is_NaN() || self.is_infinite())
}
+ ///
+ /// Returns the exponential of the number, minus `1`, in a way that is accurate
+ /// even if the number is close to zero
+ ///
+ #[inline(always)]
+ fn exp_m1(&self) -> f32 { exp_m1(*self) }
+
+ ///
+ /// Returns the natural logarithm of the number plus `1` (`ln(1+n)`) more accurately
+ /// than if the operations were performed separately
+ ///
+ #[inline(always)]
+ fn ln_1p(&self) -> f32 { ln_1p(*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
fn cosh(n: c_double) -> c_double = c_double_utils::cosh,
fn erf(n: c_double) -> c_double = c_double_utils::erf,
fn erfc(n: c_double) -> c_double = c_double_utils::erfc,
- fn expm1(n: c_double) -> c_double = c_double_utils::expm1,
+ fn exp_m1(n: c_double) -> c_double = c_double_utils::exp_m1,
fn abs_sub(a: c_double, b: c_double) -> c_double = c_double_utils::abs_sub,
fn fmax(a: c_double, b: c_double) -> c_double = c_double_utils::fmax,
fn fmin(a: c_double, b: c_double) -> c_double = c_double_utils::fmin,
fn ldexp(x: c_double, n: c_int) -> c_double = c_double_utils::ldexp,
fn lgamma(n: c_double, sign: &mut c_int) -> c_double = c_double_utils::lgamma,
fn log_radix(n: c_double) -> c_double = c_double_utils::log_radix,
- fn ln1p(n: c_double) -> c_double = c_double_utils::ln1p,
+ fn ln_1p(n: c_double) -> c_double = c_double_utils::ln_1p,
fn ilog_radix(n: c_double) -> c_int = c_double_utils::ilog_radix,
fn modf(n: c_double, iptr: &mut c_double) -> c_double = c_double_utils::modf,
fn round(n: c_double) -> c_double = c_double_utils::round,
}
impl Exponential for f64 {
+ /// Returns the exponential of the number
#[inline(always)]
fn exp(&self) -> f64 { exp(*self) }
+ /// Returns 2 raised to the power of the number
#[inline(always)]
fn exp2(&self) -> f64 { exp2(*self) }
- #[inline(always)]
- fn expm1(&self) -> f64 { expm1(*self) }
-
/// Returns the natural logarithm of the number
#[inline(always)]
fn ln(&self) -> f64 { ln(*self) }
#[inline(always)]
fn max_10_exp() -> int { 308 }
+ ///
+ /// Returns the exponential of the number, minus `1`, in a way that is accurate
+ /// even if the number is close to zero
+ ///
+ #[inline(always)]
+ fn exp_m1(&self) -> f64 { exp_m1(*self) }
+
+ ///
+ /// Returns the natural logarithm of the number plus `1` (`ln(1+n)`) more accurately
+ /// than if the operations were performed separately
+ ///
+ #[inline(always)]
+ fn ln_1p(&self) -> f64 { ln_1p(*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
pub use f64::{add, sub, mul, div, rem, lt, le, eq, ne, ge, gt};
pub use f64::{acos, asin, atan2, cbrt, ceil, copysign, cosh, floor};
-pub use f64::{erf, erfc, exp, expm1, exp2, abs_sub};
+pub use f64::{erf, erfc, exp, exp_m1, exp2, abs_sub};
pub use f64::{mul_add, fmax, fmin, next_after, frexp, hypot, ldexp};
-pub use f64::{lgamma, ln, log_radix, ln1p, log10, log2, ilog_radix};
+pub use f64::{lgamma, ln, log_radix, ln_1p, log10, log2, ilog_radix};
pub use f64::{modf, pow, powi, round, sinh, tanh, tgamma, trunc};
pub use f64::{j0, j1, jn, y0, y1, yn};
}
impl Exponential for float {
+ /// Returns the exponential of the number
#[inline(always)]
fn exp(&self) -> float {
(*self as f64).exp() as float
}
+ /// Returns 2 raised to the power of the number
#[inline(always)]
fn exp2(&self) -> float {
(*self as f64).exp2() as float
}
- #[inline(always)]
- fn expm1(&self) -> float {
- (*self as f64).expm1() as float
- }
-
/// Returns the natural logarithm of the number
#[inline(always)]
fn ln(&self) -> float {
!(self.is_NaN() || self.is_infinite())
}
+ ///
+ /// Returns the exponential of the number, minus `1`, in a way that is accurate
+ /// even if the number is close to zero
+ ///
+ #[inline(always)]
+ fn exp_m1(&self) -> float {
+ (*self as f64).exp_m1() as float
+ }
+
+ ///
+ /// Returns the natural logarithm of the number plus `1` (`ln(1+n)`) more accurately
+ /// than if the operations were performed separately
+ ///
+ #[inline(always)]
+ 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
/// produces a more accurate result with better performance than a separate multiplication
pub trait Exponential {
fn exp(&self) -> Self;
fn exp2(&self) -> Self;
- fn expm1(&self) -> Self;
fn ln(&self) -> Self;
fn log(&self, base: Self) -> Self;
fn log2(&self) -> Self;
fn min_10_exp() -> int;
fn max_10_exp() -> int;
+ fn exp_m1(&self) -> Self;
+ fn ln_1p(&self) -> Self;
fn mul_add(&self, a: Self, b: Self) -> Self;
fn next_after(&self, other: Self) -> Self;
}