1162271Srwatson/* s_tanhf.c -- float version of s_tanh.c. 2162271Srwatson * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. 3172106Srwatson */ 4162271Srwatson 5162271Srwatson/* 6162271Srwatson * ==================================================== 7162271Srwatson * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 8162271Srwatson * 9162271Srwatson * Developed at SunPro, a Sun Microsystems, Inc. business. 10162271Srwatson * Permission to use, copy, modify, and distribute this 11162271Srwatson * software is freely granted, provided that this notice 12162271Srwatson * is preserved. 13162271Srwatson * ==================================================== 14162271Srwatson */ 15162271Srwatson 16162271Srwatson#include <sys/cdefs.h> 17162271Srwatson__FBSDID("$FreeBSD$"); 18162271Srwatson 19162271Srwatson#include "math.h" 20162271Srwatson#include "math_private.h" 21162271Srwatson 22162271Srwatsonstatic const volatile float tiny = 1.0e-30; 23162271Srwatsonstatic const float one=1.0, two=2.0, huge = 1.0e30; 24162271Srwatson 25162271Srwatsonfloat 26162271Srwatsontanhf(float x) 27162271Srwatson{ 28162271Srwatson float t,z; 29162271Srwatson int32_t jx,ix; 30162271Srwatson 31162271Srwatson GET_FLOAT_WORD(jx,x); 32162271Srwatson ix = jx&0x7fffffff; 33162271Srwatson 34172106Srwatson /* x is INF or NaN */ 35162271Srwatson if(ix>=0x7f800000) { 36162271Srwatson if (jx>=0) return one/x+one; /* tanh(+-inf)=+-1 */ 37162271Srwatson else return one/x-one; /* tanh(NaN) = NaN */ 38162271Srwatson } 39162271Srwatson 40162271Srwatson /* |x| < 9 */ 41162271Srwatson if (ix < 0x41100000) { /* |x|<9 */ 42162271Srwatson if (ix<0x39800000) { /* |x|<2**-12 */ 43162271Srwatson if(huge+x>one) return x; /* tanh(tiny) = tiny with inexact */ 44162271Srwatson } 45162271Srwatson if (ix>=0x3f800000) { /* |x|>=1 */ 46172106Srwatson t = expm1f(two*fabsf(x)); 47172106Srwatson z = one - two/(t+two); 48172106Srwatson } else { 49172106Srwatson t = expm1f(-two*fabsf(x)); 50172106Srwatson z= -t/(t+two); 51172106Srwatson } 52172106Srwatson /* |x| >= 9, return +-1 */ 53162271Srwatson } else { 54172106Srwatson z = one - tiny; /* raise inexact flag */ 55162271Srwatson } 56162271Srwatson return (jx>=0)? z: -z; 57162271Srwatson} 58172106Srwatson