ReactOS 0.4.16-dev-117-g38f21f9
tanh.c File Reference
#include "libm.h"
#include "libm_util.h"
#include "libm_inlines.h"
#include "libm_errno.h"
Include dependency graph for tanh.c:

Go to the source code of this file.

Macros

#define USE_HANDLE_ERROR
 
#define USE_SPLITEXP
 
#define USE_SCALEDOUBLE_2
 
#define USE_VAL_WITH_FLAGS
 

Functions

double tanh (double x)
 

Macro Definition Documentation

◆ USE_HANDLE_ERROR

#define USE_HANDLE_ERROR

Definition at line 30 of file tanh.c.

◆ USE_SCALEDOUBLE_2

#define USE_SCALEDOUBLE_2

Definition at line 32 of file tanh.c.

◆ USE_SPLITEXP

#define USE_SPLITEXP

Definition at line 31 of file tanh.c.

◆ USE_VAL_WITH_FLAGS

#define USE_VAL_WITH_FLAGS

Definition at line 33 of file tanh.c.

Function Documentation

◆ tanh()

double tanh ( double  x)

Definition at line 46 of file tanh.c.

47{
48 /*
49 The definition of tanh(x) is sinh(x)/cosh(x), which is also equivalent
50 to the following three formulae:
51 1. (exp(x) - exp(-x))/(exp(x) + exp(-x))
52 2. (1 - (2/(exp(2*x) + 1 )))
53 3. (exp(2*x) - 1)/(exp(2*x) + 1)
54 but computationally, some formulae are better on some ranges.
55 */
56 static const double
57 thirtytwo_by_log2 = 4.61662413084468283841e+01, /* 0x40471547652b82fe */
58 log2_by_32_lead = 2.16608493356034159660e-02, /* 0x3f962e42fe000000 */
59 log2_by_32_tail = 5.68948749532545630390e-11, /* 0x3dcf473de6af278e */
60 large_threshold = 20.0; /* 0x4034000000000000 */
61
62 unsigned long long ux, aux, xneg;
63 double y, z, p, z1, z2;
64 int m;
65
66 /* Special cases */
67
68 GET_BITS_DP64(x, ux);
69 aux = ux & ~SIGNBIT_DP64;
70 if (aux < 0x3e30000000000000) /* |x| small enough that tanh(x) = x */
71 {
72 if (aux == 0)
73 return x; /* with no inexact */
74 else
75 return val_with_flags(x, AMD_F_INEXACT);
76 }
77 else if (aux > 0x7ff0000000000000) /* |x| is NaN */
78 return _handle_error("tanh", OP_TANH, ux|0x0008000000000000, _DOMAIN,
79 0, EDOM, x, 0.0, 1);
80// return x + x;
81
82 xneg = (aux != ux);
83
84 y = x;
85 if (xneg) y = -x;
86
87 if (y > large_threshold)
88 {
89 /* If x is large then exp(-x) is negligible and
90 formula 1 reduces to plus or minus 1.0 */
91 z = 1.0;
92 }
93 else if (y <= 1.0)
94 {
95 double y2;
96 y2 = y*y;
97 if (y < 0.9)
98 {
99 /* Use a [3,3] Remez approximation on [0,0.9]. */
100 z = y + y*y2*
101 (-0.274030424656179760118928e0 +
102 (-0.176016349003044679402273e-1 +
103 (-0.200047621071909498730453e-3 -
104 0.142077926378834722618091e-7*y2)*y2)*y2)/
105 (0.822091273968539282568011e0 +
106 (0.381641414288328849317962e0 +
107 (0.201562166026937652780575e-1 +
108 0.2091140262529164482568557e-3*y2)*y2)*y2);
109 }
110 else
111 {
112 /* Use a [3,3] Remez approximation on [0.9,1]. */
113 z = y + y*y2*
114 (-0.227793870659088295252442e0 +
115 (-0.146173047288731678404066e-1 +
116 (-0.165597043903549960486816e-3 -
117 0.115475878996143396378318e-7*y2)*y2)*y2)/
118 (0.683381611977295894959554e0 +
119 (0.317204558977294374244770e0 +
120 (0.167358775461896562588695e-1 +
121 0.173076050126225961768710e-3*y2)*y2)*y2);
122 }
123 }
124 else
125 {
126 /* Compute p = exp(2*y) + 1. The code is basically inlined
127 from exp_amd. */
128
129 splitexp(2*y, 1.0, thirtytwo_by_log2, log2_by_32_lead,
130 log2_by_32_tail, &m, &z1, &z2);
131 p = scaleDouble_2(z1 + z2, m) + 1.0;
132
133 /* Now reconstruct tanh from p. */
134 z = (1.0 - 2.0/p);
135 }
136
137 if (xneg) z = - z;
138 return z;
139}
double __cdecl _handle_error(char *fname, int opcode, unsigned long long value, int type, int flags, int error, double arg1, double arg2, int nargs)
Handles an error condition.
Definition: _handle_error.c:34
#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_DP64(x, ux)
Definition: libm_util.h:118
static const WCHAR aux[]
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG _In_ LONG y2
Definition: winddi.h:3711