Coverage Report

Created: 2025-10-10 06:16

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/moddable/xs/tools/fdlibm/s_tanh.c
Line
Count
Source
1
/*
2
 * ====================================================
3
 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
4
 *
5
 * Developed at SunPro, a Sun Microsystems, Inc. business.
6
 * Permission to use, copy, modify, and distribute this
7
 * software is freely granted, provided that this notice
8
 * is preserved.
9
 * ====================================================
10
 */
11
12
/* Tanh(x)
13
 * Return the Hyperbolic Tangent of x
14
 *
15
 * Method :
16
 *               x    -x
17
 *              e  - e
18
 *  0. tanh(x) is defined to be -----------
19
 *               x    -x
20
 *              e  + e
21
 *  1. reduce x to non-negative by tanh(-x) = -tanh(x).
22
 *  2.  0      <= x <  2**-28 : tanh(x) := x with inexact if x != 0
23
 *                  -t
24
 *      2**-28 <= x <  1      : tanh(x) := -----; t = expm1(-2x)
25
 *                 t + 2
26
 *                 2
27
 *      1      <= x <  22     : tanh(x) := 1 - -----; t = expm1(2x)
28
 *               t + 2
29
 *      22     <= x <= INF    : tanh(x) := 1.
30
 *
31
 * Special cases:
32
 *  tanh(NaN) is NaN;
33
 *  only tanh(0)=0 is exact for finite argument.
34
 */
35
36
#include "math_private.h"
37
38
static const volatile double tiny = 1.0e-300;
39
static const double one = 1.0, two = 2.0, huge = 1.0e300;
40
41
double
42
s_tanh(double x)
43
4.77k
{
44
4.77k
  double t,z;
45
4.77k
  int32_t jx,ix;
46
47
4.77k
  GET_HIGH_WORD(jx,x);
48
4.77k
  ix = jx&0x7fffffff;
49
50
    /* x is INF or NaN */
51
4.77k
  if(ix>=0x7ff00000) {
52
2.09k
      if (jx>=0) return one/x+one;    /* tanh(+-inf)=+-1 */
53
1.88k
      else       return one/x-one;    /* tanh(NaN) = NaN */
54
2.09k
  }
55
56
    /* |x| < 22 */
57
2.67k
  if (ix < 0x40360000) {   /* |x|<22 */
58
2.34k
      if (ix<0x3e300000) { /* |x|<2**-28 */
59
133
    if(huge+x>one) return x; /* tanh(tiny) = tiny with inexact */
60
133
      }
61
2.21k
      if (ix>=0x3ff00000) { /* |x|>=1  */
62
254
    t = s_expm1(two*fabs(x));
63
254
    z = one - two/(t+two);
64
1.95k
      } else {
65
1.95k
          t = s_expm1(-two*fabs(x));
66
1.95k
          z= -t/(t+two);
67
1.95k
      }
68
    /* |x| >= 22, return +-1 */
69
2.21k
  } else {
70
330
      z = one - tiny;   /* raise inexact flag */
71
330
  }
72
2.54k
  return (jx>=0)? z: -z;
73
2.67k
}