s_tanhf.c revision 271779
12116Sjkh/* s_tanhf.c -- float version of s_tanh.c. 22116Sjkh * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. 32116Sjkh */ 42116Sjkh 52116Sjkh/* 62116Sjkh * ==================================================== 72116Sjkh * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 82116Sjkh * 92116Sjkh * Developed at SunPro, a Sun Microsystems, Inc. business. 102116Sjkh * Permission to use, copy, modify, and distribute this 118870Srgrimes * software is freely granted, provided that this notice 122116Sjkh * is preserved. 132116Sjkh * ==================================================== 142116Sjkh */ 152116Sjkh 16176451Sdas#include <sys/cdefs.h> 17176451Sdas__FBSDID("$FreeBSD: stable/10/lib/msun/src/s_tanhf.c 271779 2014-09-18 15:10:22Z tijl $"); 182116Sjkh 192116Sjkh#include "math.h" 202116Sjkh#include "math_private.h" 212116Sjkh 22271779Stijlstatic const volatile float tiny = 1.0e-30; 23271779Stijlstatic const float one=1.0, two=2.0, huge = 1.0e30; 24271779Stijl 2597413Salfredfloat 2697413Salfredtanhf(float x) 272116Sjkh{ 282116Sjkh float t,z; 292116Sjkh int32_t jx,ix; 302116Sjkh 312116Sjkh GET_FLOAT_WORD(jx,x); 322116Sjkh ix = jx&0x7fffffff; 332116Sjkh 342116Sjkh /* x is INF or NaN */ 358870Srgrimes if(ix>=0x7f800000) { 362116Sjkh if (jx>=0) return one/x+one; /* tanh(+-inf)=+-1 */ 372116Sjkh else return one/x-one; /* tanh(NaN) = NaN */ 382116Sjkh } 392116Sjkh 40153302Sbde /* |x| < 9 */ 41153302Sbde if (ix < 0x41100000) { /* |x|<9 */ 42153302Sbde if (ix<0x39800000) { /* |x|<2**-12 */ 43153302Sbde if(huge+x>one) return x; /* tanh(tiny) = tiny with inexact */ 44153302Sbde } 452116Sjkh if (ix>=0x3f800000) { /* |x|>=1 */ 462116Sjkh t = expm1f(two*fabsf(x)); 472116Sjkh z = one - two/(t+two); 482116Sjkh } else { 492116Sjkh t = expm1f(-two*fabsf(x)); 502116Sjkh z= -t/(t+two); 512116Sjkh } 52153302Sbde /* |x| >= 9, return +-1 */ 532116Sjkh } else { 54153302Sbde z = one - tiny; /* raise inexact flag */ 552116Sjkh } 562116Sjkh return (jx>=0)? z: -z; 572116Sjkh} 58