]> git.lizzy.rs Git - rust.git/commitdiff
Implement exp_m1 and ln_1p as methods for Float
authorBrendan Zabarauskas <bjzaba@yahoo.com.au>
Mon, 6 May 2013 18:47:46 +0000 (04:47 +1000)
committerBrendan Zabarauskas <bjzaba@yahoo.com.au>
Tue, 7 May 2013 09:16:02 +0000 (19:16 +1000)
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'.

src/libcore/num/cmath.rs
src/libcore/num/f32.rs
src/libcore/num/f64.rs
src/libcore/num/float.rs
src/libcore/num/num.rs

index 8a0a88235d20cacde4fc45539b38e390b108f4ae..a80703fafa3d22918b3f7cb49c71a25dee5a0164 100644 (file)
@@ -33,7 +33,8 @@ pub mod c_double_utils {
         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
@@ -63,7 +64,7 @@ pub mod c_double_utils {
         // 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;
@@ -117,7 +118,7 @@ pub mod c_float_utils {
         #[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"]
@@ -148,7 +149,7 @@ pub mod c_float_utils {
 
         #[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;
index 8a0b6567898e0eac5ef3f90226825008350dd618..58dc6f4f45b57302770dd7ad829b8d4edb40b1c4 100644 (file)
@@ -82,7 +82,7 @@ fn copysign(x: c_float, y: c_float) -> c_float = c_float_utils::copysign,
     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,
@@ -92,7 +92,7 @@ fn hypot(x: c_float, y: c_float) -> c_float = c_float_utils::hypot,
     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,
@@ -408,15 +408,14 @@ fn atan2(&self, other: f32) -> f32 { atan2(*self, other) }
 }
 
 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) }
@@ -588,6 +587,20 @@ fn is_finite(&self) -> bool {
         !(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
index 6d2fd3d1b81b6a7d8660595baa499925476d931a..41fc9cca66e5a99afd92a4fc5c0bf6d71314c190 100644 (file)
@@ -84,7 +84,7 @@ fn copysign(x: c_double, y: c_double) -> c_double = c_double_utils::copysign,
     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,
@@ -94,7 +94,7 @@ fn hypot(x: c_double, y: c_double) -> c_double = c_double_utils::hypot,
     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,
@@ -421,15 +421,14 @@ fn atan2(&self, other: f64) -> f64 { atan2(*self, other) }
 }
 
 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) }
@@ -631,6 +630,20 @@ fn min_10_exp() -> int { -307 }
     #[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
index 18c512b485fb1897187082f2f880aba286942943..512d3afc2b622180f6542de4184524544f908d30 100644 (file)
@@ -26,9 +26,9 @@
 
 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};
 
@@ -532,21 +532,18 @@ fn atan2(&self, other: float) -> float {
 }
 
 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 {
@@ -823,6 +820,24 @@ fn is_finite(&self) -> bool {
         !(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
index 7fcd16c199a705a1b83e50d79c02689e0c141f69..2496ba497dcc4c5f4397d731fbc3f56048cd4119 100644 (file)
@@ -121,7 +121,6 @@ pub trait Trigonometric {
 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;
@@ -261,6 +260,8 @@ pub trait Float: Real
     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;
 }