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: releng/10.2/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