add missing bitshift for __expo2 and move it into its own module

This commit is contained in:
Lukas Wirth 2018-07-14 19:14:56 +02:00
parent 85d7ebd422
commit 92b7592ba2
3 changed files with 20 additions and 13 deletions

View file

@ -2,6 +2,7 @@ use core::f64;
use super::exp;
use super::expm1;
use super::k_expo2;
pub fn cosh(mut x: f64) -> f64 {
let t: f64;
@ -31,20 +32,10 @@ pub fn cosh(mut x: f64) -> f64 {
/* |x| > log(DBL_MAX) or nan */
/* note: the result is stored to handle overflow */
t = __expo2(x);
t = k_expo2(x);
return t;
}
const K: u32 = 2043;
pub fn __expo2(x: f64) -> f64 {
let kln2 = f64::from_bits(0x40962066151add8b);
/* note that k is odd and scale*scale overflows */
let scale = f64::from_bits(((0x3ff + K / 2) << 20) as u64);
/* exp(x - k ln2) * 2**(k-1) */
return exp(x - kln2) * scale * scale;
}
#[cfg(test)]
mod tests {
#[test]

View file

@ -0,0 +1,12 @@
use super::exp;
const K: u32 = 2043;
const KLN2: f64 = 1416.0996898839683;
#[inline]
pub(crate) fn k_expo2(x: f64) -> f64 {
/* note that k is odd and scale*scale overflows */
let scale = f64::from_bits((((0x3ff + K / 2) << 20) as u64) << 32);
/* exp(x - k ln2) * 2**(k-1) */
return exp(x - KLN2) * scale * scale;
}

View file

@ -43,8 +43,8 @@ pub use self::ceil::ceil;
pub use self::ceilf::ceilf;
pub use self::cosf::cosf;
pub use self::cosh::cosh;
pub use self::expf::expf;
pub use self::exp::exp;
pub use self::expf::expf;
pub use self::expm1::expm1;
pub use self::fabs::fabs;
pub use self::fabsf::fabsf;
@ -72,11 +72,15 @@ pub use self::trunc::trunc;
pub use self::truncf::truncf;
mod k_cosf;
mod k_expo2;
mod k_sinf;
mod rem_pio2_large;
mod rem_pio2f;
use self::{k_cosf::k_cosf, k_sinf::k_sinf, rem_pio2_large::rem_pio2_large, rem_pio2f::rem_pio2f};
use self::{
k_cosf::k_cosf, k_expo2::k_expo2, k_sinf::k_sinf, rem_pio2_large::rem_pio2_large,
rem_pio2f::rem_pio2f,
};
fn isnanf(x: f32) -> bool {
x.to_bits() & 0x7fffffff > 0x7f800000