Coverage Report

Created: 2025-10-28 07:25

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
2.37k
{
44
2.37k
  double t,z;
45
2.37k
  int32_t jx,ix;
46
47
2.37k
  GET_HIGH_WORD(jx,x);
48
2.37k
  ix = jx&0x7fffffff;
49
50
    /* x is INF or NaN */
51
2.37k
  if(ix>=0x7ff00000) {
52
480
      if (jx>=0) return one/x+one;    /* tanh(+-inf)=+-1 */
53
267
      else       return one/x-one;    /* tanh(NaN) = NaN */
54
480
  }
55
56
    /* |x| < 22 */
57
1.89k
  if (ix < 0x40360000) {   /* |x|<22 */
58
1.87k
      if (ix<0x3e300000) { /* |x|<2**-28 */
59
55
    if(huge+x>one) return x; /* tanh(tiny) = tiny with inexact */
60
55
      }
61
1.81k
      if (ix>=0x3ff00000) { /* |x|>=1  */
62
196
    t = s_expm1(two*fabs(x));
63
196
    z = one - two/(t+two);
64
1.62k
      } else {
65
1.62k
          t = s_expm1(-two*fabs(x));
66
1.62k
          z= -t/(t+two);
67
1.62k
      }
68
    /* |x| >= 22, return +-1 */
69
1.81k
  } else {
70
25
      z = one - tiny;   /* raise inexact flag */
71
25
  }
72
1.84k
  return (jx>=0)? z: -z;
73
1.89k
}