Back to index

glibc  2.9
s_tanhf.c
Go to the documentation of this file.
00001 /* s_tanhf.c -- float version of s_tanh.c.
00002  * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
00003  */
00004 
00005 /*
00006  * ====================================================
00007  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
00008  *
00009  * Developed at SunPro, a Sun Microsystems, Inc. business.
00010  * Permission to use, copy, modify, and distribute this
00011  * software is freely granted, provided that this notice
00012  * is preserved.
00013  * ====================================================
00014  */
00015 
00016 #if defined(LIBM_SCCS) && !defined(lint)
00017 static char rcsid[] = "$NetBSD: s_tanhf.c,v 1.4 1995/05/10 20:48:24 jtc Exp $";
00018 #endif
00019 
00020 #include "math.h"
00021 #include "math_private.h"
00022 
00023 #ifdef __STDC__
00024 static const float one=1.0, two=2.0, tiny = 1.0e-30;
00025 #else
00026 static float one=1.0, two=2.0, tiny = 1.0e-30;
00027 #endif
00028 
00029 #ifdef __STDC__
00030        float __tanhf(float x)
00031 #else
00032        float __tanhf(x)
00033        float x;
00034 #endif
00035 {
00036        float t,z;
00037        int32_t jx,ix;
00038 
00039        GET_FLOAT_WORD(jx,x);
00040        ix = jx&0x7fffffff;
00041 
00042     /* x is INF or NaN */
00043        if(ix>=0x7f800000) {
00044            if (jx>=0) return one/x+one;    /* tanh(+-inf)=+-1 */
00045            else       return one/x-one;    /* tanh(NaN) = NaN */
00046        }
00047 
00048     /* |x| < 22 */
00049        if (ix < 0x41b00000) {             /* |x|<22 */
00050            if (ix == 0)
00051               return x;            /* x == +-0 */
00052            if (ix<0x24000000)             /* |x|<2**-55 */
00053               return x*(one+x);           /* tanh(small) = small */
00054            if (ix>=0x3f800000) {   /* |x|>=1  */
00055               t = __expm1f(two*fabsf(x));
00056               z = one - two/(t+two);
00057            } else {
00058                t = __expm1f(-two*fabsf(x));
00059                z= -t/(t+two);
00060            }
00061     /* |x| > 22, return +-1 */
00062        } else {
00063            z = one - tiny;         /* raised inexact flag */
00064        }
00065        return (jx>=0)? z: -z;
00066 }
00067 weak_alias (__tanhf, tanhf)