Skip to content

Commit

Permalink
Merge #111
Browse files Browse the repository at this point in the history
111: Implement tanh r=japaric a=porglezomp

Closes #37

Co-authored-by: C Jones <code@calebjones.net>
  • Loading branch information
bors[bot] and porglezomp committed Jul 15, 2018
2 parents be34a06 + 935c393 commit 8da2707
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 3 deletions.
2 changes: 0 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,6 @@ pub trait F64Ext: private::Sealed {
#[cfg(todo)]
fn cosh(self) -> Self;

#[cfg(todo)]
fn tanh(self) -> Self;

#[cfg(todo)]
Expand Down Expand Up @@ -595,7 +594,6 @@ impl F64Ext for f64 {
cosh(self)
}

#[cfg(todo)]
#[inline]
fn tanh(self) -> Self {
tanh(self)
Expand Down
2 changes: 2 additions & 0 deletions src/math/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ mod sqrt;
mod sqrtf;
mod tan;
mod tanf;
mod tanh;
mod tanhf;
mod trunc;
mod truncf;
Expand Down Expand Up @@ -114,6 +115,7 @@ pub use self::sqrt::sqrt;
pub use self::sqrtf::sqrtf;
pub use self::tan::tan;
pub use self::tanf::tanf;
pub use self::tanh::tanh;
pub use self::tanhf::tanhf;
pub use self::trunc::trunc;
pub use self::truncf::truncf;
Expand Down
52 changes: 52 additions & 0 deletions src/math/tanh.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use super::expm1;

/* tanh(x) = (exp(x) - exp(-x))/(exp(x) + exp(-x))
* = (exp(2*x) - 1)/(exp(2*x) - 1 + 2)
* = (1 - exp(-2*x))/(exp(-2*x) - 1 + 2)
*/
pub fn tanh(mut x: f64) -> f64 {
let mut uf: f64 = x;
let mut ui: u64 = f64::to_bits(uf);

let w: u32;
let sign: bool;
let mut t: f64;

/* x = |x| */
sign = ui >> 63 != 0;
ui &= !1 / 2;
uf = f64::from_bits(ui);
x = uf;
w = (ui >> 32) as u32;

if w > 0x3fe193ea {
/* |x| > log(3)/2 ~= 0.5493 or nan */
if w > 0x40340000 {
/* |x| > 20 or nan */
/* note: this branch avoids raising overflow */
t = 1.0 - 0.0 / x;
} else {
t = expm1(2.0 * x);
t = 1.0 - 2.0 / (t + 2.0);
}
} else if w > 0x3fd058ae {
/* |x| > log(5/3)/2 ~= 0.2554 */
t = expm1(2.0 * x);
t = t / (t + 2.0);
} else if w >= 0x00100000 {
/* |x| >= 0x1p-1022, up to 2ulp error in [0.1,0.2554] */
t = expm1(-2.0 * x);
t = -t / (t + 2.0);
} else {
/* |x| is subnormal */
/* note: the branch above would not raise underflow in [0x1p-1023,0x1p-1022) */
force_eval!(x as f32);
t = x;
}

if sign {
-t
} else {
t
}
}
2 changes: 1 addition & 1 deletion test-generator/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,7 @@ f64_f64! {
sinh,
sqrt,
tan,
// tanh,
tanh,
trunc,
fabs,
}
Expand Down

0 comments on commit 8da2707

Please sign in to comment.