ReactOS 0.4.15-dev-8349-g6f277e9
tanhf.c File Reference
#include "libm.h"
#include "libm_util.h"
#include "libm_inlines.h"
#include "libm_errno.h"
Include dependency graph for tanhf.c:

Go to the source code of this file.

Macros

#define USE_HANDLE_ERRORF
 
#define USE_SPLITEXPF
 
#define USE_SCALEFLOAT_2
 
#define USE_VALF_WITH_FLAGS
 

Functions

float tanhf (float x)
 

Macro Definition Documentation

◆ USE_HANDLE_ERRORF

#define USE_HANDLE_ERRORF

Definition at line 30 of file tanhf.c.

◆ USE_SCALEFLOAT_2

#define USE_SCALEFLOAT_2

Definition at line 32 of file tanhf.c.

◆ USE_SPLITEXPF

#define USE_SPLITEXPF

Definition at line 31 of file tanhf.c.

◆ USE_VALF_WITH_FLAGS

#define USE_VALF_WITH_FLAGS

Definition at line 33 of file tanhf.c.

Function Documentation

◆ tanhf()

float tanhf ( float  x)

Definition at line 49 of file tanhf.c.

50{
51 /*
52 The definition of tanh(x) is sinh(x)/cosh(x), which is also equivalent
53 to the following three formulae:
54 1. (exp(x) - exp(-x))/(exp(x) + exp(-x))
55 2. (1 - (2/(exp(2*x) + 1 )))
56 3. (exp(2*x) - 1)/(exp(2*x) + 1)
57 but computationally, some formulae are better on some ranges.
58 */
59 static const float
60 thirtytwo_by_log2 = 4.6166240692e+01F, /* 0x4238aa3b */
61 log2_by_32_lead = 2.1659851074e-02F, /* 0x3cb17000 */
62 log2_by_32_tail = 9.9831822808e-07F, /* 0x3585fdf4 */
63 large_threshold = 10.0F; /* 0x41200000 */
64
65 unsigned int ux, aux;
66 float y, z, p, z1, z2, xneg;
67 int m;
68
69 /* Special cases */
70
71 GET_BITS_SP32(x, ux);
72 aux = ux & ~SIGNBIT_SP32;
73 if (aux < 0x39000000) /* |x| small enough that tanh(x) = x */
74 {
75 if (aux == 0)
76 return x; /* with no inexact */
77 else
78 return valf_with_flags(x, AMD_F_INEXACT);
79 }
80 else if (aux > 0x7f800000) /* |x| is NaN */
81 {
82 unsigned int ufx;
83 GET_BITS_SP32(x, ufx);
84 return _handle_errorf("tanhf", OP_TANH, ufx|0x00400000, _DOMAIN, 0,
85 EDOM, x, 0.0F, 1);
86 }
87// return x + x;
88
89 xneg = 1.0F - 2.0F * (aux != ux);
90
91 y = xneg * x;
92
93 if (y > large_threshold)
94 {
95 /* If x is large then exp(-x) is negligible and
96 formula 1 reduces to plus or minus 1.0 */
97 z = 1.0F;
98 }
99 else if (y <= 1.0F)
100 {
101 float y2;
102 y2 = y*y;
103
104 if (y < 0.9F)
105 {
106 /* Use a [2,1] Remez approximation on [0,0.9]. */
107 z = y + y*y2*
108 (-0.28192806108402678e0F +
109 (-0.14628356048797849e-2F +
110 0.4891631088530669873e-4F*y2)*y2)/
111 (0.845784192581041099e0F +
112 0.3427017942262751343e0F*y2);
113 }
114 else
115 {
116 /* Use a [2,1] Remez approximation on [0.9,1]. */
117 z = y + y*y2*
118 (-0.24069858695196524e0F +
119 (-0.12325644183611929e-2F +
120 0.3827534993599483396e-4F*y2)*y2)/
121 (0.72209738473684982e0F +
122 0.292529068698052819e0F*y2);
123 }
124 }
125 else
126 {
127 /* Compute p = exp(2*y) + 1. The code is basically inlined
128 from exp_amd. */
129
130 splitexpf(2*y, 1.0F, thirtytwo_by_log2, log2_by_32_lead,
131 log2_by_32_tail, &m, &z1, &z2);
132 p = scaleFloat_2(z1 + z2, m) + 1.0F;
133 /* Now reconstruct tanh from p. */
134 z = (1.0F - 2.0F/p);
135 }
136
137 return xneg * z;
138}
float __cdecl _handle_errorf(char *fname, int opcode, unsigned long long value, int type, int flags, int error, float arg1, float arg2, int nargs)
Definition: _handle_error.c:56
#define EDOM
Definition: errno.h:39
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLfloat GLfloat p
Definition: glext.h:8902
GLdouble GLdouble z
Definition: glext.h:5874
const GLfloat * m
Definition: glext.h:10848
#define _DOMAIN
Definition: math.h:39
#define AMD_F_INEXACT
Definition: libm_new.h:82
#define GET_BITS_SP32(x, ux)
Definition: libm_util.h:105
static const WCHAR aux[]
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG _In_ LONG y2
Definition: winddi.h:3711