amath  1.8.5
Simple command line calculator
mathr.h File Reference

Real numbers math library. More...

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define PI   3.1415926535897932384626433832795028841971693994
 
#define EULERS   2.7182818284590452353602874713526624977572470937
 
#define INFP   0x7FF0000000000000ull
 
#define INFN   0xFFF0000000000000ull
 
#define NAN   0x7FFFFFFFFFFFFFFFull
 
#define sgn(x)   (x > 0 ? 1 : x < 0 ? -1 : 0)
 
#define abs(x)   (x > 0 ? x : -x)
 

Functions

double fabs (double x)
 Returns the absolute value of x. More...
 
double ceil (double x)
 Ceiling function. More...
 
double floor (double x)
 Floor function. More...
 
double round (double x)
 Round function. More...
 
double trunc (double x)
 Truncate function. More...
 
double exp (double x)
 Returns the exponential of x. More...
 
double sqrt (double x)
 Square root function. More...
 
double cbrt (double x)
 Cube root function. More...
 
double log (double x)
 Natural logarithm function (base e) More...
 
double log10 (double x)
 Base 10 logarithm function. More...
 
double cos (double x)
 Cosine function. More...
 
double sin (double x)
 Sine function. More...
 
double tan (double x)
 Tangent function. More...
 
double sec (double x)
 Secant function. More...
 
double csc (double x)
 Cosecant function. More...
 
double cot (double x)
 Cotangent function. More...
 
double exs (double x)
 Exsecant function. More...
 
double exc (double x)
 Excosecant function. More...
 
double crd (double x)
 Chord function. More...
 
double acos (double x)
 Inverse cosine function. More...
 
double asin (double x)
 Inverse sine function. More...
 
double atan (double x)
 Inverse tangent function. More...
 
double asec (double x)
 Inverse secant function. More...
 
double acsc (double x)
 Inverse cosecant function. More...
 
double acot (double x)
 Inverse cotangent function. More...
 
double aexs (double x)
 Inverse exsecant function. More...
 
double aexc (double x)
 Inverse excosecant function. More...
 
double acrd (double x)
 Inverse chord function. More...
 
double cosh (double x)
 Hyperbolic cosine function. More...
 
double sinh (double x)
 Hyperbolic sine function. More...
 
double tanh (double x)
 Hyperbolic tangent function. More...
 
double sech (double x)
 Hyperbolic secant function. More...
 
double csch (double x)
 Hyperbolic cosecant function. More...
 
double coth (double x)
 Hyperbolic cotangent function. More...
 
double acosh (double x)
 Inverse hyperbolic cosine function. More...
 
double asinh (double x)
 Inverse hyperbolic sine function. More...
 
double atanh (double x)
 Inverse hyperbolic tangent function. More...
 
double asech (double x)
 Inverse hyperbolic secant function. More...
 
double acsch (double x)
 Inverse hyperbolic cosecant function. More...
 
double acoth (double x)
 Inverse hyperbolic cotangent function. More...
 
double ver (double x)
 Versed sine function. More...
 
double vcs (double x)
 Versed cosine function. More...
 
double cvs (double x)
 Coversed sine function. More...
 
double cvc (double x)
 Coversed cosine function. More...
 
double hv (double x)
 Haversed sine function. More...
 
double hvc (double x)
 Haversed cosine function. More...
 
double hcv (double x)
 Hacoversed sine function. More...
 
double hcc (double x)
 Hacoversed cosine function. More...
 
double aver (double x)
 Inverse versed sine function. More...
 
double avcs (double x)
 Inverse versed sine. More...
 
double acvs (double x)
 Inverse coversed sine function. More...
 
double acvc (double x)
 Inverse versed cosine. More...
 
double ahv (double x)
 Inverse haversed sine. More...
 
double ahvc (double x)
 Inverse haversed cosine. More...
 
double ahcv (double x)
 Inverse hacoversed sine. More...
 
double ahcc (double x)
 Inverse hacoversed cosine. More...
 
double pow (double x, double y)
 Expontation function. More...
 
double fmod (double x, double y)
 Return x mod y in exact arithmetic. More...
 
double atan2 (double y, double x)
 Inverse tangent function. More...
 
double hypot (double x, double y)
 hypot More...
 
double log2p (double x, double y)
 
double log1p (double x)
 
double expm1 (double x)
 
double scalbn (double x, int n)
 
double copysign (double x, double y)
 Returns a value with the magnitude of x and with the sign bit of y. More...
 
int rempio2 (double x, double *y)
 
unsigned int log2i (unsigned int x)
 

Detailed Description

Real numbers math library.

The library is based on fdlib by Sun Microsystems.

The original library can be downloaded at netlib.org:
http://www.netlib.org/fdlibm/

or from mirror site hensa.ac.uk:
http://www.hensa.ac.uk/

More info on double precision floating point at Wikipedia:
https://wikipedia.org/wiki/Double-precision_floating-point_format

Author
Carsten Sonne Larsen <cs@in.nosp@m.nola.nosp@m.n.net>

Definition in file mathr.h.

Macro Definition Documentation

◆ abs

#define abs (   x)    (x > 0 ? x : -x)

Definition at line 55 of file mathr.h.

◆ EULERS

#define EULERS   2.7182818284590452353602874713526624977572470937

Definition at line 50 of file mathr.h.

◆ INFN

#define INFN   0xFFF0000000000000ull

Definition at line 52 of file mathr.h.

◆ INFP

#define INFP   0x7FF0000000000000ull

Definition at line 51 of file mathr.h.

◆ NAN

#define NAN   0x7FFFFFFFFFFFFFFFull

Definition at line 53 of file mathr.h.

◆ PI

#define PI   3.1415926535897932384626433832795028841971693994

Definition at line 49 of file mathr.h.

◆ sgn

#define sgn (   x)    (x > 0 ? 1 : x < 0 ? -1 : 0)

Definition at line 54 of file mathr.h.

Function Documentation

◆ acos()

double acos ( double  x)

Inverse cosine function.

Method
    acos(x)  = pi/2 - asin(x)
    acos(-x) = pi/2 + asin(x)
    For |x|<=0.5
    acos(x)  = pi/2 - (x + x*x^2*R(x^2))        (see asin.c)
    For x>0.5
    acos(x)  = pi/2 - (pi/2 - 2asin(sqrt((1-x)/2)))
             = 2asin(sqrt((1-x)/2))
             = 2s + 2s*z*R(z)   ...z=(1-x)/2, s=sqrt(z)
             = 2f + (2c + 2s*z*R(z))
    where f=hi part of s, and c = (z-f*f)/(s+f) is the correction term
    for f so that f+c ~ sqrt(z).
    For x<-0.5
    acos(x)  = pi - 2asin(sqrt((1-|x|)/2))
             = pi - 0.5*(s+s*z*R(z)), where z=(1-|x|)/2,s=sqrt(z)
Special cases
    if x is NaN, return NaN
    if |x|>1, return NaN

Definition at line 92 of file acos.c.

References one, pi, pio2_hi, pio2_lo, pS0, pS1, pS2, pS3, pS4, pS5, qS1, qS2, qS3, qS4, and sqrt().

Referenced by ahvc(), RealNumber::ArcCosine(), asec(), and avcs().

93 {
94  double z, p, q, r, w, s, c, df;
95  int32_t hx, ix;
96  uint32_t lx;
97 
98  GET_HIGH_WORD(hx, x);
99  ix = hx & 0x7FFFFFFF;
100 
101  // |x| >= 1
102  if (ix >= 0x3FF00000)
103  {
104  GET_LOW_WORD(lx, x);
105 
106  // |x|==1
107  if (((ix - 0x3FF00000) | lx) == 0)
108  {
109  if (hx > 0)
110  {
111  // acos(1) = 0
112  return 0.0;
113  }
114 
115  // acos(-1) = pi
116  return pi + 2.0 * pio2_lo;
117  }
118 
119  // acos(|x|>1) is NaN
120  return NAN;
121  }
122 
123  // |x| < 0.5
124  if (ix < 0x3FE00000)
125  {
126  // if |x|<2**-57
127  if (ix <= 0x3C600000)
128  {
129  return pio2_hi + pio2_lo;
130  }
131  z = x * x;
132  p = z * (pS0 + z * (pS1 + z * (pS2 + z * (pS3 + z * (pS4 + z * pS5)))));
133  q = one + z * (qS1 + z * (qS2 + z * (qS3 + z * qS4)));
134  r = p / q;
135  return pio2_hi - (x - (pio2_lo - x * r));
136  }
137 
138  // x < -0.5
139  if (hx < 0)
140  {
141  z = (one + x) * 0.5;
142  p = z * (pS0 + z * (pS1 + z * (pS2 + z * (pS3 + z * (pS4 + z * pS5)))));
143  q = one + z * (qS1 + z * (qS2 + z * (qS3 + z * qS4)));
144  s = sqrt(z);
145  r = p / q;
146  w = r * s - pio2_lo;
147  return pi - 2.0 * (s + w);
148  }
149 
150  // x > 0.5
151  z = (one - x) * 0.5;
152  s = sqrt(z);
153  df = s;
154  SET_LOW_WORD(df, 0);
155  c = (z - df * df) / (s + df);
156  p = z * (pS0 + z * (pS1 + z * (pS2 + z * (pS3 + z * (pS4 + z * pS5)))));
157  q = one + z * (qS1 + z * (qS2 + z * (qS3 + z * qS4)));
158  r = p / q;
159  w = r * s + c;
160  return 2.0 * (df + w);
161 }
static const double pi
Definition: acos.c:50
static const double pS2
Definition: acos.c:55
#define GET_HIGH_WORD(i, d)
Get the more significant 32 bit int from a double.
Definition: prim.h:167
static const double pS4
Definition: acos.c:57
static const double pio2_hi
Definition: acos.c:51
#define GET_LOW_WORD(i, d)
Get the less significant 32 bit int from a double.
Definition: prim.h:177
static const double pS5
Definition: acos.c:58
static const double pS0
Definition: acos.c:53
#define NAN
Definition: mathr.h:53
static const double one
Definition: acos.c:49
static const double qS4
Definition: acos.c:62
#define SET_LOW_WORD(d, v)
Set the less significant 32 bits of a double from an int.
Definition: prim.h:209
static const double qS3
Definition: acos.c:61
double sqrt(double x)
Square root function.
Definition: sqrt.c:119
static const double qS1
Definition: acos.c:59
static const double pS3
Definition: acos.c:56
static const double qS2
Definition: acos.c:60
static const double pio2_lo
Definition: acos.c:52
static const double pS1
Definition: acos.c:54
Here is the call graph for this function:
Here is the caller graph for this function:

◆ acosh()

double acosh ( double  x)

Inverse hyperbolic cosine function.

Based on
    acosh(x) = log [ x + sqrt(x*x-1) ]
we have
    acosh(x) = log(x)+ln2, if x is large; else
    acosh(x) = log(2x-1/(sqrt(x*x-1)+x)) if x>2; else
    acosh(x) = log1p(t+sqrt(2.0*t+t*t)); where t=x-1
Special cases
    acosh(x) is NaN if x<1
    acosh(NaN) is NaN

Definition at line 69 of file acosh.c.

References ln2, log(), log1p(), one, and sqrt().

Referenced by RealNumber::HypArcCosine().

70 {
71  double t;
72  int32_t hx, lx;
73 
74  GET_HIGH_WORD(hx, x);
75  GET_LOW_WORD(lx, x);
76 
77  // x < 1
78  if (hx < 0x3FF00000)
79  {
80  return NAN;
81  }
82 
83  // x > 2**28
84  if (hx >= 0x41B00000)
85  {
86  // x is inf or NaN
87  if (hx >= 0x7FF00000)
88  {
89  return NAN;
90  }
91 
92  // acosh(huge) = log(2x)
93  return log(x) + ln2;
94  }
95 
96  // acosh(1) = 0
97  if (((hx - 0x3FF00000) | lx) == 0)
98  {
99  return 0.0;
100  }
101 
102  // 2**28 > x > 2
103  if (hx > 0x40000000)
104  {
105  t = x * x;
106  return log(2.0 * x - one / (x + sqrt(t - one)));
107  }
108 
109  // 1 < x < 2
110  t = x - one;
111  return log1p(t + sqrt(2.0 * t + t * t));
112 }
static const double one
Definition: acosh.c:49
#define GET_HIGH_WORD(i, d)
Get the more significant 32 bit int from a double.
Definition: prim.h:167
#define GET_LOW_WORD(i, d)
Get the less significant 32 bit int from a double.
Definition: prim.h:177
#define NAN
Definition: mathr.h:53
double log1p(double x)
Definition: log1p.c:122
static const double ln2
Definition: acosh.c:50
double sqrt(double x)
Square root function.
Definition: sqrt.c:119
double log(double x)
Natural logarithm function (base e)
Definition: log.c:109
Here is the call graph for this function:
Here is the caller graph for this function:

◆ acot()

double acot ( double  x)

Inverse cotangent function.

Method
    arccot(x) = arctan(1/x)

Definition at line 45 of file acot.c.

References atan().

Referenced by RealNumber::ArcCotangent().

46 {
47  double a = 1.0 / x;
48  double b = atan(a);
49  return b;
50 }
double atan(double x)
Inverse tangent function.
Definition: atan.c:103
Here is the call graph for this function:
Here is the caller graph for this function:

◆ acoth()

double acoth ( double  x)

Inverse hyperbolic cotangent function.

Method
                          x + 1
    acoth(x) = 0.5 * ln( ----— )
                          x - 1
    when x in [-1, 1]
    acoth(x) = NaN

Definition at line 49 of file acoth.c.

References log().

Referenced by RealNumber::HypArcCotangent().

50 {
51  double a, b, c, d;
52 
53  if (x <= 1 && x >= -1)
54  {
55  return NAN;
56  }
57 
58  a = x + 1.0;
59  b = x - 1.0;
60  c = a / b;
61  d = 0.5 * log(c);
62  return d;
63 }
#define NAN
Definition: mathr.h:53
double log(double x)
Natural logarithm function (base e)
Definition: log.c:109
Here is the call graph for this function:
Here is the caller graph for this function:

◆ acrd()

double acrd ( double  x)

Inverse chord function.

Method
    arccrd(x) = 2*arcsin(x/2)

Definition at line 45 of file acrd.c.

References asin().

Referenced by RealNumber::ArcChord().

46 {
47  double a = x / 2.0;
48  double b = asin(a);
49  double c = 2.0 * b;
50  return c;
51 }
double asin(double x)
Inverse sine function.
Definition: asin.c:100
Here is the call graph for this function:
Here is the caller graph for this function:

◆ acsc()

double acsc ( double  x)

Inverse cosecant function.

Method
    arccsc(x) = arcsin(1/x)

Definition at line 45 of file acsc.c.

References asin().

Referenced by RealNumber::ArcCosecant().

46 {
47  double a = 1.0 / x;
48  double b = asin(a);
49  return b;
50 }
double asin(double x)
Inverse sine function.
Definition: asin.c:100
Here is the call graph for this function:
Here is the caller graph for this function:

◆ acsch()

double acsch ( double  x)

Inverse hyperbolic cosecant function.

Method
                    1+sqrt(1+x*x)
    acsch(x) = ln( ------------— )
                          x
    when x is 0
    acsch(x) = NaN

Definition at line 49 of file acsch.c.

References log(), and sqrt().

Referenced by RealNumber::HypArcCosecant().

50 {
51  double a, b, c, d, e, f;
52 
53  if (TRIG_INEXACT(x))
54  {
55  return NAN;
56  }
57 
58  a = x * x;
59  b = a + 1.0;
60  c = sqrt(b);
61  d = 1.0 + c;
62  e = d / x;
63  f = log(e);
64  return f;
65 }
#define TRIG_INEXACT(x)
Definition: prim.h:48
#define NAN
Definition: mathr.h:53
double sqrt(double x)
Square root function.
Definition: sqrt.c:119
double log(double x)
Natural logarithm function (base e)
Definition: log.c:109
Here is the call graph for this function:
Here is the caller graph for this function:

◆ acvc()

double acvc ( double  x)

Inverse versed cosine.

Method
    acvc(x) = asin(1+x)

Definition at line 45 of file acvc.c.

References asin().

Referenced by RealNumber::ArcCoVerCosine().

46 {
47  return asin(1.0 + x);
48 }
double asin(double x)
Inverse sine function.
Definition: asin.c:100
Here is the call graph for this function:
Here is the caller graph for this function:

◆ acvs()

double acvs ( double  x)

Inverse coversed sine function.

Definition at line 40 of file acvs.c.

References atan(), and sqrt().

Referenced by RealNumber::ArcCoVerSine().

41 {
42  double a = 1.0 - x;
43  double b = 2.0 * x - x * x;
44  double c = sqrt(b);
45  double d = atan(a / c);
46  return d;
47 }
double atan(double x)
Inverse tangent function.
Definition: atan.c:103
double sqrt(double x)
Square root function.
Definition: sqrt.c:119
Here is the call graph for this function:
Here is the caller graph for this function:

◆ aexc()

double aexc ( double  x)

Inverse excosecant function.

Method
    aexcsc(x) = arccsc(x+1)
              = arcsin(1/(x+1))

Definition at line 46 of file aexc.c.

References asin().

Referenced by RealNumber::ArcExCosecant().

47 {
48  double a, b, c;
49 
50  if (x > -2.0 && x < 0.0)
51  return NAN;
52 
53  a = x + 1;
54  b = 1 / a;
55  c = asin(b);
56  return c;
57 }
double asin(double x)
Inverse sine function.
Definition: asin.c:100
#define NAN
Definition: mathr.h:53
Here is the call graph for this function:
Here is the caller graph for this function:

◆ aexs()

double aexs ( double  x)

Inverse exsecant function.

Method
    aexsec(x) = arcsec(x+1)
              = arccos(1/(x+1))
              = arctan(sqrt(x^2+2*X))

Definition at line 47 of file aexs.c.

References atan(), and sqrt().

Referenced by RealNumber::ArcExSecant().

48 {
49  double a, b, c;
50 
51  if (x > -2.0 && x < 0.0)
52  return NAN;
53 
54  a = x * x + 2 * x;
55  b = sqrt(a);
56  c = atan(b);
57  return c;
58 }
double atan(double x)
Inverse tangent function.
Definition: atan.c:103
#define NAN
Definition: mathr.h:53
double sqrt(double x)
Square root function.
Definition: sqrt.c:119
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ahcc()

double ahcc ( double  x)

Inverse hacoversed cosine.

Definition at line 40 of file ahcc.c.

Referenced by RealNumber::ArcHaCoVerCosine().

41 {
42  // TODO: Implement ahcc(double)
43  return NAN;
44 }
#define NAN
Definition: mathr.h:53
Here is the caller graph for this function:

◆ ahcv()

double ahcv ( double  x)

Inverse hacoversed sine.

Definition at line 40 of file ahcv.c.

Referenced by RealNumber::ArcHaCoVerSine().

41 {
42  // TODO: Implement ahcv(double)
43  return NAN;
44 }
#define NAN
Definition: mathr.h:53
Here is the caller graph for this function:

◆ ahv()

double ahv ( double  x)

Inverse haversed sine.

Definition at line 40 of file ahv.c.

References atan(), and sqrt().

Referenced by RealNumber::ArcHaVerSine().

41 {
42  double a = x - x * x;
43  double b = 2.0 * sqrt(a);
44  double c = 1.0 - 2.0 * x;
45  double d = atan(b / c);
46  return d;
47 }
double atan(double x)
Inverse tangent function.
Definition: atan.c:103
double sqrt(double x)
Square root function.
Definition: sqrt.c:119
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ahvc()

double ahvc ( double  x)

Inverse haversed cosine.

Definition at line 40 of file ahvc.c.

References acos(), and sqrt().

Referenced by RealNumber::ArcHaVerCosine().

41 {
42  double a = sqrt(x);
43  double b = acos(a);
44  double c = 2.0 * b;
45  return c;
46 }
double acos(double x)
Inverse cosine function.
Definition: acos.c:92
double sqrt(double x)
Square root function.
Definition: sqrt.c:119
Here is the call graph for this function:
Here is the caller graph for this function:

◆ asec()

double asec ( double  x)

Inverse secant function.

Method
    arcsec(x) = arccos(1/x)

Definition at line 45 of file asec.c.

References acos().

Referenced by RealNumber::ArcSecant().

46 {
47  double a = 1.0 / x;
48  double b = acos(a);
49  return b;
50 }
double acos(double x)
Inverse cosine function.
Definition: acos.c:92
Here is the call graph for this function:
Here is the caller graph for this function:

◆ asech()

double asech ( double  x)

Inverse hyperbolic secant function.

Method
                    1+sqrt(1-x*x)
    asech(x) = ln( ------------— )
                          x
    when x <= 0
    asech(x) = NaN
    when x > 1
    asech(x) = NaN

Definition at line 52 of file asech.c.

References log(), and sqrt().

Referenced by RealNumber::HypArcSecant().

53 {
54  double a, b, c, d, e, f;
55 
56  if (TRIG_INEXACT(x) || x < 0.0 || x > 1.0)
57  {
58  return NAN;
59  }
60 
61  a = x * x;
62  b = 1.0 - a;
63  c = sqrt(b);
64  d = 1.0 + c;
65  e = d / x;
66  f = log(e);
67  return f;
68 }
#define TRIG_INEXACT(x)
Definition: prim.h:48
#define NAN
Definition: mathr.h:53
double sqrt(double x)
Square root function.
Definition: sqrt.c:119
double log(double x)
Natural logarithm function (base e)
Definition: log.c:109
Here is the call graph for this function:
Here is the caller graph for this function:

◆ asin()

double asin ( double  x)

Inverse sine function.

Method
Since  asin(x) = x + x^3/6 + x^5*3/40 + x^7*15/336 + ...
we approximate asin(x) on [0,0.5] by
     asin(x) = x + x*x^2*R(x^2)
where
     R(x^2) is a rational approximation of (asin(x)-x)/x^3
and its remez error is bounded by
     |(asin(x)-x)/x^3 - R(x^2)| < 2^(-58.75)
For x in [0.5,1]
     asin(x) = pi/2-2*asin(sqrt((1-x)/2))
Let y = (1-x), z = y/2, s := sqrt(z), and pio2_hi+pio2_lo=pi/2;
then for x>0.98
     asin(x) = pi/2 - 2*(s+s*z*R(z))
             = pio2_hi - (2*(s+s*z*R(z)) - pio2_lo)
For x<=0.98, let pio4_hi = pio2_hi/2, then
     f = hi part of s;
     c = sqrt(z) - f = (z-f*f)/(s+f)     ...f+c=sqrt(z)
and
     asin(x) = pi/2 - 2*(s+s*z*R(z))
             = pio4_hi+(pio4-2s)-(2s*z*R(z)-pio2_lo)
             = pio4_hi+(pio4-2f)-(2s*z*R(z)-(pio2_lo+2c))
Special cases
    if x is NaN, return NaN
    if |x|>1, return NaN

Definition at line 100 of file asin.c.

References fabs(), huge, one, pio2_hi, pio2_lo, pio4_hi, pS0, pS1, pS2, pS3, pS4, pS5, qS1, qS2, qS3, qS4, and sqrt().

Referenced by acrd(), acsc(), acvc(), aexc(), and RealNumber::ArcSine().

101 {
102  double t, w, p, q, c, r, s;
103  int32_t hx, ix;
104  GET_HIGH_WORD(hx, x);
105  ix = hx & 0x7fffffff;
106  if (ix >= 0x3ff00000)
107  { /* |x|>= 1 */
108  uint32_t lx;
109  GET_LOW_WORD(lx, x);
110  if (((ix - 0x3ff00000) | lx) == 0)
111  /* asin(1)=+-pi/2 with inexact */
112  return x * pio2_hi + x * pio2_lo;
113  return NAN; /* asin(|x|>1) is NaN */
114  }
115  else if (ix < 0x3fe00000)
116  { /* |x|<0.5 */
117  if (ix < 0x3e400000)
118  { /* if |x| < 2**-27 */
119  if (huge + x > one)
120  {
121  return x; /* return x with inexact if x!=0*/
122  }
123  else
124  {
125  t = 0;
126  }
127  }
128  else
129  {
130  t = x * x;
131  }
132 
133  p = t * (pS0 + t * (pS1 + t * (pS2 + t * (pS3 + t * (pS4 + t * pS5)))));
134  q = one + t * (qS1 + t * (qS2 + t * (qS3 + t * qS4)));
135  w = p / q;
136  return x + x * w;
137  }
138  /* 1> |x|>= 0.5 */
139  w = one - fabs(x);
140  t = w * 0.5;
141  p = t * (pS0 + t * (pS1 + t * (pS2 + t * (pS3 + t * (pS4 + t * pS5)))));
142  q = one + t * (qS1 + t * (qS2 + t * (qS3 + t * qS4)));
143  s = sqrt(t);
144  if (ix >= 0x3FEF3333)
145  { /* if |x| > 0.975 */
146  w = p / q;
147  t = pio2_hi - (2.0 * (s + s * w) - pio2_lo);
148  }
149  else
150  {
151  w = s;
152  SET_LOW_WORD(w, 0);
153  c = (t - w * w) / (s + w);
154  r = p / q;
155  p = 2.0 * s * r - (pio2_lo - 2.0 * c);
156  q = pio4_hi - 2.0 * w;
157  t = pio4_hi - (p - q);
158  }
159  if (hx > 0)
160  return t;
161  else
162  return -t;
163 }
static const double pS1
Definition: asin.c:56
#define GET_HIGH_WORD(i, d)
Get the more significant 32 bit int from a double.
Definition: prim.h:167
static const double huge
Definition: asin.c:50
static const double pS4
Definition: asin.c:59
static const double pS5
Definition: asin.c:60
static const double pio2_hi
Definition: asin.c:51
#define GET_LOW_WORD(i, d)
Get the less significant 32 bit int from a double.
Definition: prim.h:177
static const double qS1
Definition: asin.c:61
static const double pio4_hi
Definition: asin.c:53
static const double pS0
Definition: asin.c:55
#define NAN
Definition: mathr.h:53
static const double pS2
Definition: asin.c:57
static const double qS4
Definition: asin.c:64
static const double one
Definition: asin.c:49
static const double pS3
Definition: asin.c:58
static const double pio2_lo
Definition: asin.c:52
#define SET_LOW_WORD(d, v)
Set the less significant 32 bits of a double from an int.
Definition: prim.h:209
double sqrt(double x)
Square root function.
Definition: sqrt.c:119
static const double qS2
Definition: asin.c:62
double fabs(double x)
Returns the absolute value of x.
Definition: fabs.c:51
static const double qS3
Definition: asin.c:63
Here is the call graph for this function:
Here is the caller graph for this function:

◆ asinh()

double asinh ( double  x)

Inverse hyperbolic sine function.

Method
    Based on
    asinh(x) = sign(x) * log [ |x| + sqrt(x*x+1) ]
    we have
    asinh(x) = x  if  1+x*x=1,
             = sign(x)*(log(x)+ln2)) for large |x|, else
             = sign(x)*log(2|x|+1/(|x|+sqrt(x*x+1))) if|x|>2, else
             = sign(x)*log1p(|x| + x^2/(1 + sqrt(1+x^2)))

Definition at line 68 of file asinh.c.

References fabs(), huge, ln2, log(), log1p(), one, and sqrt().

Referenced by RealNumber::HypArcSine().

69 {
70  double t, w;
71  int32_t hx, ix;
72  GET_HIGH_WORD(hx, x);
73  ix = hx & 0x7fffffff;
74  if (ix >= 0x7ff00000)
75  return x + x; /* x is inf or NaN */
76  if (ix < 0x3e300000)
77  { /* |x|<2**-28 */
78  if (huge + x > one)
79  return x; /* return x inexact except 0 */
80  }
81  if (ix > 0x41b00000)
82  { /* |x| > 2**28 */
83  w = log(fabs(x)) + ln2;
84  }
85  else if (ix > 0x40000000)
86  { /* 2**28 > |x| > 2.0 */
87  t = fabs(x);
88  w = log(2.0 * t + one / (sqrt(x * x + one) + t));
89  }
90  else
91  { /* 2.0 > |x| > 2**-28 */
92  t = x * x;
93  w = log1p(fabs(x) + t / (one + sqrt(one + t)));
94  }
95  if (hx > 0)
96  return w;
97  else
98  return -w;
99 }
#define GET_HIGH_WORD(i, d)
Get the more significant 32 bit int from a double.
Definition: prim.h:167
static const double ln2
Definition: asinh.c:50
static const double huge
Definition: asinh.c:51
static const double one
Definition: asinh.c:49
double log1p(double x)
Definition: log1p.c:122
double sqrt(double x)
Square root function.
Definition: sqrt.c:119
double fabs(double x)
Returns the absolute value of x.
Definition: fabs.c:51
double log(double x)
Natural logarithm function (base e)
Definition: log.c:109
Here is the call graph for this function:
Here is the caller graph for this function:

◆ atan()

double atan ( double  x)

Inverse tangent function.

Method
    1. Reduce x to positive by atan(x) = -atan(-x).
    2. According to the integer k=4t+0.25 chopped, t=x, the argument
       is further reduced to one of the following intervals and the
       arctangent of t is evaluated by the corresponding formula:
    [0,7/16]      atan(x) = t-t^3*(a1+t^2*(a2+...(a10+t^2*a11)...)
    [7/16,11/16]  atan(x) = atan(1/2) + atan( (t-0.5)/(1+t/2) )
    [11/16.19/16] atan(x) = atan( 1 ) + atan( (t-1)/(1+t) )
    [19/16,39/16] atan(x) = atan(3/2) + atan( (t-1.5)/(1+1.5t) )
    [39/16,INF]   atan(x) = atan(INF) + atan( -1/t )
Constants
    The hexadecimal values are the intended ones for the following
    constants. The decimal values may be used, provided that the
    compiler will convert from decimal to binary accurately enough
    to produce the hexadecimal values shown.

Definition at line 103 of file atan.c.

References aT, atanhi, atanlo, fabs(), huge, and one.

Referenced by acot(), acvs(), aexs(), ahv(), RealNumber::ArcTangent(), atan2(), and aver().

104 {
105  double w, s1, s2, z;
106  int32_t ix, hx, id;
107 
108  GET_HIGH_WORD(hx, x);
109  ix = hx & 0x7fffffff;
110  if (ix >= 0x44100000)
111  { /* if |x| >= 2^66 */
112  uint32_t low;
113 
114  GET_LOW_WORD(low, x);
115  if (ix > 0x7ff00000 || (ix == 0x7ff00000 && (low != 0)))
116  return NAN;
117  if (hx > 0)
118  return atanhi[3] + atanlo[3];
119  else
120  return -atanhi[3] - atanlo[3];
121  }
122  if (ix < 0x3fdc0000)
123  { /* |x| < 0.4375 */
124  if (ix < 0x3e200000)
125  { /* |x| < 2^-29 */
126  if (huge + x > one)
127  return x; /* raise inexact */
128  }
129  id = -1;
130  }
131  else
132  {
133  x = fabs(x);
134  if (ix < 0x3ff30000)
135  { /* |x| < 1.1875 */
136  if (ix < 0x3fe60000)
137  { /* 7/16 <=|x|<11/16 */
138  id = 0;
139  x = (2.0 * x - one) / (2.0 + x);
140  }
141  else
142  { /* 11/16<=|x|< 19/16 */
143  id = 1;
144  x = (x - one) / (x + one);
145  }
146  }
147  else
148  {
149  if (ix < 0x40038000)
150  { /* |x| < 2.4375 */
151  id = 2;
152  x = (x - 1.5) / (one + 1.5 * x);
153  }
154  else
155  { /* 2.4375 <= |x| < 2^66 */
156  id = 3;
157  x = -1.0 / x;
158  }
159  }
160  }
161  /* end of argument reduction */
162  z = x * x;
163  w = z * z;
164  /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */
165  s1 = z * (aT[0] + w * (aT[2] + w * (aT[4] + w * (aT[6] + w * (aT[8] + w * aT[10])))));
166  s2 = w * (aT[1] + w * (aT[3] + w * (aT[5] + w * (aT[7] + w * aT[9]))));
167  if (id < 0)
168  {
169  return x - x * (s1 + s2);
170  }
171 
172  z = atanhi[id] - ((x * (s1 + s2) - atanlo[id]) - x);
173  return (hx < 0) ? -z : z;
174 }
#define GET_HIGH_WORD(i, d)
Get the more significant 32 bit int from a double.
Definition: prim.h:167
static const double huge
Definition: atan.c:78
#define GET_LOW_WORD(i, d)
Get the less significant 32 bit int from a double.
Definition: prim.h:177
static const double aT[]
Definition: atan.c:62
static const double atanhi[]
Definition: atan.c:48
#define NAN
Definition: mathr.h:53
static const double one
Definition: atan.c:77
static const double atanlo[]
Definition: atan.c:55
double fabs(double x)
Returns the absolute value of x.
Definition: fabs.c:51
Here is the call graph for this function:
Here is the caller graph for this function:

◆ atan2()

double atan2 ( double  y,
double  x 
)

Inverse tangent function.

Parameters
y,x
Method
    1. Reduce y to positive by atan2(y,x)=-atan2(-y,x).
    2. Reduce x to positive by (if x and y are unexceptional):
       ARG (x+iy) = arctan(y/x)           ... if x > 0,
       ARG (x+iy) = pi - arctan[y/(-x)]   ... if x < 0,
Special cases
    ATAN2((anything), NaN ) is NaN;
    ATAN2(NAN , (anything) ) is NaN;
    ATAN2(+-0, +(anything but NaN)) is +-0  ;
    ATAN2(+-0, -(anything but NaN)) is +-pi ;
    ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2;
    ATAN2(+-(anything but INF and NaN), +INF) is +-0 ;
    ATAN2(+-(anything but INF and NaN), -INF) is +-pi;
    ATAN2(+-INF,+INF ) is +-pi/4 ;
    ATAN2(+-INF,-INF ) is +-3pi/4;
    ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2;
Constants
    The hexadecimal values are the intended ones for the following
    constants. The decimal values may be used, provided that the
    compiler will convert from decimal to binary accurately enough
    to produce the hexadecimal values shown.

Definition at line 87 of file atan2.c.

References atan(), fabs(), pi, pi_lo, pi_o_2, pi_o_4, tiny, and zero.

Referenced by clog(), and cpow().

88 {
89  double z;
90  int32_t k, m, hx, hy, ix, iy;
91  uint32_t lx, ly;
92 
93  EXTRACT_WORDS(hx, lx, x);
94  ix = hx & 0x7fffffff;
95  EXTRACT_WORDS(hy, ly, y);
96  iy = hy & 0x7fffffff;
97  if (((ix | ((lx | -lx) >> 31)) > 0x7ff00000) ||
98  ((iy | ((ly | -ly) >> 31)) > 0x7ff00000)) /* x or y is NaN */
99  return x + y;
100  if (((hx - 0x3ff00000) | lx) == 0)
101  return atan(y); /* x=1.0 */
102  m = ((hy >> 31) & 1) | ((hx >> 30) & 2); /* 2*sign(x)+sign(y) */
103 
104  /* when y = 0 */
105  if ((iy | ly) == 0)
106  {
107  switch (m)
108  {
109  case 0:
110  case 1:
111  return y; /* atan(+-0,+anything)=+-0 */
112  case 2:
113  return pi + tiny; /* atan(+0,-anything) = pi */
114  case 3:
115  return -pi - tiny; /* atan(-0,-anything) =-pi */
116  }
117  }
118  /* when x = 0 */
119  if ((ix | lx) == 0)
120  return (hy < 0) ? -pi_o_2 - tiny : pi_o_2 + tiny;
121 
122  /* when x is INF */
123  if (ix == 0x7ff00000)
124  {
125  if (iy == 0x7ff00000)
126  {
127  switch (m)
128  {
129  case 0:
130  return pi_o_4 + tiny; /* atan(+INF,+INF) */
131  case 1:
132  return -pi_o_4 - tiny; /* atan(-INF,+INF) */
133  case 2:
134  return 3.0 * pi_o_4 + tiny; /*atan(+INF,-INF)*/
135  case 3:
136  return -3.0 * pi_o_4 - tiny; /*atan(-INF,-INF)*/
137  }
138  }
139  else
140  {
141  switch (m)
142  {
143  case 0:
144  return zero; /* atan(+...,+INF) */
145  case 1:
146  return -zero; /* atan(-...,+INF) */
147  case 2:
148  return pi + tiny; /* atan(+...,-INF) */
149  case 3:
150  return -pi - tiny; /* atan(-...,-INF) */
151  }
152  }
153  }
154  /* when y is INF */
155  if (iy == 0x7ff00000)
156  return (hy < 0) ? -pi_o_2 - tiny : pi_o_2 + tiny;
157 
158  /* compute y/x */
159  k = (iy - ix) >> 20;
160  if (k > 60)
161  z = pi_o_2 + 0.5 * pi_lo; /* |y/x| > 2**60 */
162  else if (hx < 0 && k < -60)
163  z = 0.0; /* |y|/x < -2**60 */
164  else
165  z = atan(fabs(y / x)); /* safe to do y/x */
166  switch (m)
167  {
168  case 0:
169  return z; /* atan(+,+) */
170  case 1:
171  {
172  uint32_t zh;
173  GET_HIGH_WORD(zh, z);
174  SET_HIGH_WORD(z, zh ^ 0x80000000);
175  }
176  return z; /* atan(-,+) */
177  case 2:
178  return pi - (z - pi_lo); /* atan(+,-) */
179  default: /* case 3 */
180  return (z - pi_lo) - pi; /* atan(-,-) */
181  }
182 }
static const double pi
Definition: atan2.c:53
double atan(double x)
Inverse tangent function.
Definition: atan.c:103
#define GET_HIGH_WORD(i, d)
Get the more significant 32 bit int from a double.
Definition: prim.h:167
#define EXTRACT_WORDS(ix0, ix1, d)
Get two 32 bit ints from a double.
Definition: prim.h:156
static const double pi_lo
Definition: atan2.c:54
static const double pi_o_2
Definition: atan2.c:52
static const double tiny
Definition: atan2.c:49
static const double zero
Definition: atan2.c:50
static const double pi_o_4
Definition: atan2.c:51
#define SET_HIGH_WORD(d, v)
Set the more significant 32 bits of a double from an int.
Definition: prim.h:198
double fabs(double x)
Returns the absolute value of x.
Definition: fabs.c:51
Here is the call graph for this function:
Here is the caller graph for this function:

◆ atanh()

double atanh ( double  x)

Inverse hyperbolic tangent function.

Method
1.Reduced x to positive by atanh(-x) = -atanh(x)
2.For x>=0.5
              1               2x                         x
  atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------)
              2             1 - x                      1 - x

  For x<0.5
  atanh(x) = 0.5*log1p(2x+2x*x/(1-x))
Special cases
    atanh(x) is NaN if |x| > 1
    atanh(NaN) is that NaN
    atanh(+-1) is +-INF

Definition at line 72 of file atanh.c.

References huge, log1p(), one, and zero.

Referenced by RealNumber::HypArcTangent().

73 {
74  double t;
75  int32_t hx, ix;
76  uint32_t lx;
77  GET_HIGH_WORD(hx, x);
78  GET_LOW_WORD(lx, x);
79  ix = hx & 0x7FFFFFFF;
80 
81  // |x| > 1
82  if ((ix | ((lx | (-lx)) >> 31)) > 0x3FF00000)
83  {
84  return NAN;
85  }
86 
87  if (ix == 0x3FF00000)
88  return x / zero;
89  if (ix < 0x3E300000 && (huge + x) > zero)
90  return x; /* x<2**-28 */
91  SET_HIGH_WORD(x, ix); /* x <- |x| */
92  if (ix < 0x3FE00000)
93  { /* x < 0.5 */
94  t = x + x;
95  t = 0.5 * log1p(t + t * x / (one - x));
96  }
97  else
98  t = 0.5 * log1p((x + x) / (one - x));
99 
100  if (hx >= 0)
101  {
102  return t;
103  }
104 
105  return -t;
106 }
#define GET_HIGH_WORD(i, d)
Get the more significant 32 bit int from a double.
Definition: prim.h:167
#define GET_LOW_WORD(i, d)
Get the less significant 32 bit int from a double.
Definition: prim.h:177
static double zero
Definition: atanh.c:49
#define NAN
Definition: mathr.h:53
static const double huge
Definition: atanh.c:48
static const double one
Definition: atanh.c:48
double log1p(double x)
Definition: log1p.c:122
#define SET_HIGH_WORD(d, v)
Set the more significant 32 bits of a double from an int.
Definition: prim.h:198
Here is the call graph for this function:
Here is the caller graph for this function:

◆ avcs()

double avcs ( double  x)

Inverse versed sine.

avcs(x) = acos(1+x)

Definition at line 44 of file avcs.c.

References acos().

Referenced by RealNumber::ArcVerCosine().

45 {
46  return acos(1.0 + x);
47 }
double acos(double x)
Inverse cosine function.
Definition: acos.c:92
Here is the call graph for this function:
Here is the caller graph for this function:

◆ aver()

double aver ( double  x)

Inverse versed sine function.

Definition at line 40 of file aver.c.

References atan(), and sqrt().

Referenced by RealNumber::ArcVerSine().

41 {
42  double a, b, c, d;
43 
44  if (x < 0.0 || x > 2.0)
45  {
46  return NAN;
47  }
48 
49  a = 2.0 * x - x * x;
50  b = sqrt(a);
51  c = 1.0 - x;
52 
53  if (TRIG_INEXACT(c))
54  {
55  return INFP;
56  }
57 
58  d = atan(b / c);
59  return d;
60 }
double atan(double x)
Inverse tangent function.
Definition: atan.c:103
#define INFP
Definition: mathr.h:51
#define TRIG_INEXACT(x)
Definition: prim.h:48
#define NAN
Definition: mathr.h:53
double sqrt(double x)
Square root function.
Definition: sqrt.c:119
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cbrt()

double cbrt ( double  x)

Cube root function.

Definition at line 62 of file cbrt.c.

References B1, B2, C, D, E, F, and G.

Referenced by RealNumber::CubeRoot().

63 {
64  int32_t hx, lx, ht;
65  double r, s, t = 0.0, w;
66  uint32_t sign;
67 
68  GET_HIGH_WORD(hx, x);
69 
70  // sign = sign(x)
71  sign = hx & 0x80000000;
72  hx ^= sign;
73 
74  // cbrt(NaN,INF) is itself
75  if (hx >= 0x7FF00000)
76  {
77  return x + x;
78  }
79 
80  GET_LOW_WORD(lx, x);
81 
82  // cbrt(0) is itself
83  if ((hx | lx) == 0)
84  {
85  return x;
86  }
87 
88  // x <- |x|
89  SET_HIGH_WORD(x, hx);
90 
91  // rough cbrt to 5 bits
92  if (hx < 0x00100000) // subnormal number
93  {
94  SET_HIGH_WORD(t, 0x43500000); // set t= 2**54
95  t *= x;
96  GET_HIGH_WORD(ht, t);
97  SET_HIGH_WORD(t, ht / 3 + B2);
98  }
99  else
100  {
101  SET_HIGH_WORD(t, hx / 3 + B1);
102  }
103 
104  // new cbrt to 23 bits, may be implemented in single precision
105  r = t * t / x;
106  s = C + r * t;
107  t *= G + F / (s + E + D / s);
108 
109  // chopped to 20 bits and make it larger than cbrt(x)
110  SET_LOW_WORD(t, 0);
111  GET_HIGH_WORD(ht, t);
112  SET_HIGH_WORD(t, ht + 0x00000001);
113 
114  // one step newton iteration to 53 bits with error less than 0.667 ulps
115  s = t * t; // t*t is exact
116  r = x / s;
117  w = t + t;
118  r = (r - t) / (w + r); // r-s is exact
119  t = t + t * r;
120 
121  // retore the sign bit
122  GET_HIGH_WORD(ht, t);
123  SET_HIGH_WORD(t, ht | sign);
124 
125  return (t);
126 }
static const double D
Definition: cbrt.c:54
static const double E
Definition: cbrt.c:55
#define GET_HIGH_WORD(i, d)
Get the more significant 32 bit int from a double.
Definition: prim.h:167
#define GET_LOW_WORD(i, d)
Get the less significant 32 bit int from a double.
Definition: prim.h:177
static const double F
Definition: cbrt.c:56
static const unsigned B2
Definition: cbrt.c:50
static const double G
Definition: cbrt.c:57
static const unsigned B1
Definition: cbrt.c:49
static const double C
Definition: cbrt.c:53
#define SET_LOW_WORD(d, v)
Set the less significant 32 bits of a double from an int.
Definition: prim.h:209
#define SET_HIGH_WORD(d, v)
Set the more significant 32 bits of a double from an int.
Definition: prim.h:198
Here is the caller graph for this function:

◆ ceil()

double ceil ( double  x)

Ceiling function.

Parameters
x
Returns
x rounded toward -inf to integral value
Method
    Bit twiddling
Exception
    Inexact flag raised if x not equal to ceil(x).

Definition at line 63 of file ceil.c.

References huge.

Referenced by cceil(), RealNumber::Ceiling(), Dragon4(), round(), and trunc().

64 {
65  int32_t i0,i1,j0;
66  uint32_t i,j;
67  EXTRACT_WORDS(i0,i1,x);
68  j0 = ((i0>>20)&0x7ff)-0x3ff;
69  if(j0<20) {
70  if(j0<0) { /* raise inexact if x != 0 */
71  if(huge+x>0.0) { /* return 0*sign(x) if |x|<1 */
72  if(i0<0) {
73  i0=0x80000000;
74  i1=0;
75  }
76  else if((i0|i1)!=0) {
77  i0=0x3ff00000;
78  i1=0;
79  }
80  }
81  } else {
82  i = (0x000fffff)>>j0;
83  if(((i0&i)|i1)==0) return x; /* x is integral */
84  if(huge+x>0.0) { /* raise inexact flag */
85  if(i0>0) i0 += (0x00100000)>>j0;
86  i0 &= (~i);
87  i1=0;
88  }
89  }
90  } else if (j0>51) {
91  if(j0==0x400) return x+x; /* inf or NaN */
92  else return x; /* x is integral */
93  } else {
94  i = ((uint32_t)(0xffffffff))>>(j0-20);
95  if((i1&i)==0) return x; /* x is integral */
96  if(huge+x>0.0) { /* raise inexact flag */
97  if(i0>0) {
98  if(j0==20) i0+=1;
99  else {
100  j = i1 + (1<<(52-j0));
101  // NOTICE: Is this a correct cast?
102  if((int32_t)j<(int32_t)i1) i0+=1; /* got a carry */
103  i1 = j;
104  }
105  }
106  i1 &= (~i);
107  }
108  }
109  INSERT_WORDS(x,i0,i1);
110  return x;
111 }
#define INSERT_WORDS(d, ix0, ix1)
Set a double from two 32 bit ints.
Definition: prim.h:187
static const double huge
Definition: ceil.c:48
#define EXTRACT_WORDS(ix0, ix1, d)
Get two 32 bit ints from a double.
Definition: prim.h:156
Here is the caller graph for this function:

◆ copysign()

double copysign ( double  x,
double  y 
)

Returns a value with the magnitude of x and with the sign bit of y.

Definition at line 47 of file csign.c.

Referenced by scalbn().

48 {
49  uint32_t hx, hy;
50  GET_HIGH_WORD(hx, x);
51  GET_HIGH_WORD(hy, y);
52  SET_HIGH_WORD(x, (hx & 0x7fffffff) | (hy & 0x80000000));
53  return x;
54 }
#define GET_HIGH_WORD(i, d)
Get the more significant 32 bit int from a double.
Definition: prim.h:167
#define SET_HIGH_WORD(d, v)
Set the more significant 32 bits of a double from an int.
Definition: prim.h:198
Here is the caller graph for this function:

◆ cos()

double cos ( double  x)

Cosine function.

Parameters
x
Returns
Cosine function of x
Kernel function:
__kernel_sin        ... sine function on [-pi/4,pi/4]
__kernel_cos        ... cose function on [-pi/4,pi/4]
__ieee754_rem_pio2  ... argument reduction routine
Method:
Let S,C and T denote the sin, cos and tan respectively on
[-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
in [-pi/4 , +pi/4], and let n = k mod 4.

We have

     n        sin(x)      cos(x)        tan(x)
----------------------------------------------------------
     0          S           C             T
     1          C          -S           -1/T
     2         -S          -C             T
     3         -C           S           -1/T
----------------------------------------------------------
Special cases:
Let trig be any of sin, cos, or tan.
trig(+-INF)  is NaN
trig(NaN)    is that NaN
Accuracy:
TRIG(x) returns trig(x) nearly rounded

Definition at line 87 of file cos.c.

References __kernel_cos(), __kernel_sin(), and rempio2().

Referenced by cchc(), ccos(), ccosh(), ccot(), ccoth(), ccsc(), ccsch(), cexp(), RealNumber::Cosine(), cot(), cpow(), csc(), csec(), csech(), csin(), csinh(), ctan(), ctanh(), hv(), hvc(), sec(), and vcs().

88 {
89  double y[2], z = 0.0;
90  int32_t n, ix;
91 
92  // High word of x
93  GET_HIGH_WORD(ix, x);
94  ix &= 0x7FFFFFFF;
95 
96  // |x| ~< pi/4
97  if (ix <= 0x3FE921FB)
98  {
99  return __kernel_cos(x, z);
100  }
101 
102  // cos(Inf or NaN) is NaN
103  if (ix >= 0x7FF00000)
104  {
105  return NAN;
106  }
107 
108  // argument reduction needed
109  n = rempio2(x, y);
110  switch (n & 3)
111  {
112  case 0:
113  return __kernel_cos(y[0], y[1]);
114  case 1:
115  return -__kernel_sin(y[0], y[1], 1);
116  case 2:
117  return -__kernel_cos(y[0], y[1]);
118  default:
119  return __kernel_sin(y[0], y[1], 1);
120  }
121 }
#define GET_HIGH_WORD(i, d)
Get the more significant 32 bit int from a double.
Definition: prim.h:167
double __kernel_cos(double x, double y)
Kernel cosine function.
Definition: kcos.c:94
#define NAN
Definition: mathr.h:53
int rempio2(double x, double *y)
Definition: remp2.c:104
double __kernel_sin(double x, double y, int iy)
Kernel sin function.
Definition: ksin.c:89
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cosh()

double cosh ( double  x)

Hyperbolic cosine function.

Mathematically cosh(x) if defined to be (exp(x)+exp(-x))/2

Method
1. Replace x by |x| (cosh(x) = cosh(-x))
2.
                                              [ exp(x) - 1 ]^2
   0        <= x <= ln2/2  :  cosh(x) := 1 + -------------------
                                                2*exp(x)

                                         exp(x) +  1/exp(x)
   ln2/2    <= x <= 22     :  cosh(x) := -------------------
                                                 2
   22       <= x <= lnovft :  cosh(x) := exp(x)/2
   lnovft   <= x <= ln2ovft:  cosh(x) := exp(x/2)/2 * exp(x/2)
   ln2ovft  <  x           :  cosh(x) := huge*huge (overflow)
Special cases:
cosh(x) is |x| if x is +INF, -INF, or NaN
only cosh(0)=1 is exact for finite x

Definition at line 83 of file cosh.c.

References exp(), expm1(), fabs(), half, huge, and one.

Referenced by cchc(), cchsh(), ccot(), ccoth(), ccsc(), ccsch(), coth(), csec(), csech(), ctan(), ctanh(), RealNumber::HypCosine(), and sech().

84 {
85  double t, w;
86  int32_t ix;
87  uint32_t lx;
88 
89  // High word of |x|
90  GET_HIGH_WORD(ix, x);
91  ix &= 0x7FFFFFFF;
92 
93  // x is INF or NaN
94  if (ix >= 0x7FF00000)
95  {
96  return x * x;
97  }
98 
99  // |x| in [0,0.5*ln2]
100  if (ix < 0x3FD62E43)
101  {
102  t = expm1(fabs(x));
103  w = one + t;
104  if (ix < 0x3C800000)
105  {
106  // cosh(tiny) = 1
107  return w;
108  }
109 
110  return one + (t * t) / (w + w);
111  }
112 
113  // |x| in [0.5*ln2,22]
114  if (ix < 0x40360000)
115  {
116  t = exp(fabs(x));
117  return half * t + half / t;
118  }
119 
120  // |x| in [22, log(maxdouble)]
121  if (ix < 0x40862E42)
122  {
123  return half * exp(fabs(x));
124  }
125 
126  // |x| in [log(maxdouble), overflowthresold]
127  lx = *((((*(unsigned *)&one) >> 29)) + (unsigned *)&x);
128  if (ix < 0x408633CE || ((ix == 0x408633CE) && (lx <= (unsigned)0x8FB9F87D)))
129  {
130  w = exp(half * fabs(x));
131  t = half * w;
132  return t * w;
133  }
134 
135  // |x| > overflowthresold, cosh(x) overflow
136  return huge * huge;
137 }
#define GET_HIGH_WORD(i, d)
Get the more significant 32 bit int from a double.
Definition: prim.h:167
double exp(double x)
Returns the exponential of x.
Definition: exp.c:138
static const double one
Definition: cosh.c:53
double expm1(double x)
Definition: expm1.c:153
double fabs(double x)
Returns the absolute value of x.
Definition: fabs.c:51
static const double huge
Definition: cosh.c:55
static const double half
Definition: cosh.c:54
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cot()

double cot ( double  x)

Cotangent function.

Parameters
x
cot(x) = 1/tan(x)
       = cos(x)/sin(x)
       = sin(2*x)/(cos(2*x)-1)

Definition at line 47 of file cot.c.

References cos(), and sin().

Referenced by RealNumber::Cotangent().

48 {
49  double a, b, c;
50 
51  a = cos(x);
52  b = sin(x);
53 
54  if (TRIG_INEXACT(b))
55  {
56  return NAN;
57  }
58 
59  c = a / b;
60  return c;
61 }
double sin(double x)
Sine function.
Definition: sin.c:86
double cos(double x)
Cosine function.
Definition: cos.c:87
#define TRIG_INEXACT(x)
Definition: prim.h:48
#define NAN
Definition: mathr.h:53
Here is the call graph for this function:
Here is the caller graph for this function:

◆ coth()

double coth ( double  x)

Hyperbolic cotangent function.

coth(x) = cosh(x)/sinh(x)

Definition at line 44 of file coth.c.

References cosh(), and sinh().

Referenced by RealNumber::HypCotangent().

45 {
46  double a, b, c;
47 
48  a = cosh(x);
49  b = sinh(x);
50 
51  if (TRIG_INEXACT(b))
52  {
53  return NAN;
54  }
55 
56  c = a / b;
57  return c;
58 }
double cosh(double x)
Hyperbolic cosine function.
Definition: cosh.c:83
double sinh(double x)
Hyperbolic sine function.
Definition: sinh.c:77
#define TRIG_INEXACT(x)
Definition: prim.h:48
#define NAN
Definition: mathr.h:53
Here is the call graph for this function:
Here is the caller graph for this function:

◆ crd()

double crd ( double  x)

Chord function.

crd(x) = 2*sin(x/2)

Definition at line 44 of file crd.c.

References sin().

Referenced by RealNumber::Chord().

45 {
46  double a = x / 2.0;
47  double b = sin(a);
48  double c = 2.0 * b;
49  return c;
50 }
double sin(double x)
Sine function.
Definition: sin.c:86
Here is the call graph for this function:
Here is the caller graph for this function:

◆ csc()

double csc ( double  x)

Cosecant function.

csc = sin(1/x)
    = -2*sin(x)/(cos(2*x) - 1)

Definition at line 45 of file csc.c.

References cos(), and sin().

Referenced by RealNumber::Cosecant(), and exc().

46 {
47  double a, b, c;
48 
49  b = cos(2.0 * x) - 1.0;
50  if (b == 0.0)
51  {
52  return NAN;
53  }
54 
55  a = -2.0 * sin(x);
56  c = a / b;
57  return c;
58 }
double sin(double x)
Sine function.
Definition: sin.c:86
double cos(double x)
Cosine function.
Definition: cos.c:87
#define NAN
Definition: mathr.h:53
Here is the call graph for this function:
Here is the caller graph for this function:

◆ csch()

double csch ( double  x)

Hyperbolic cosecant function.

csch(x) = 1/sinh(x)

Definition at line 44 of file csch.c.

References sinh().

Referenced by RealNumber::HypCosecant().

45 {
46  double a = sinh(x);
47  if (TRIG_INEXACT(a))
48  {
49  return NAN;
50  }
51  return 1.0 / a;
52 }
double sinh(double x)
Hyperbolic sine function.
Definition: sinh.c:77
#define TRIG_INEXACT(x)
Definition: prim.h:48
#define NAN
Definition: mathr.h:53
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cvc()

double cvc ( double  x)

Coversed cosine function.

cvc(x) = 1+sin(x)

Definition at line 44 of file cvc.c.

References sin().

Referenced by RealNumber::CoVerCosine().

45 {
46  return 1.0 + sin(x);
47 }
double sin(double x)
Sine function.
Definition: sin.c:86
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cvs()

double cvs ( double  x)

Coversed sine function.

cvs(x) = 1-sin(x)

Definition at line 44 of file cvs.c.

References sin().

Referenced by RealNumber::CoVerSine(), and exc().

45 {
46  return 1.0 - sin(x);
47 }
double sin(double x)
Sine function.
Definition: sin.c:86
Here is the call graph for this function:
Here is the caller graph for this function:

◆ exc()

double exc ( double  x)

Excosecant function.

excsc(x) = csc(x)-1
         = (1-sin(x))/sin(x)
         = cvs(x)/sin(x)
         = cvs(x)*csc(x)

Definition at line 47 of file exc.c.

References csc(), and cvs().

Referenced by RealNumber::ExCosecant().

48 {
49  return cvs(x) * csc(x);
50 }
double csc(double x)
Cosecant function.
Definition: csc.c:45
double cvs(double x)
Coversed sine function.
Definition: cvs.c:44
Here is the call graph for this function:
Here is the caller graph for this function:

◆ exp()

double exp ( double  x)

Returns the exponential of x.

Method
1. Argument reduction:
   Reduce x to an r so that |r| <= 0.5*ln2 ~ 0.34658.
   Given x, find r and integer k such that

           x = k*ln2 + r,  |r| <= 0.5*ln2.

   Here r will be represented as r = hi-lo for better
   accuracy.

2. Approximation of exp(r) by a special rational function on
   the interval [0,0.34658]:

   Write
       R(r**2) = r*(exp(r)+1)/(exp(r)-1) = 2 + r*r/6 - r**4/360 + ...
   We use a special Remes algorithm on [0,0.34658] to generate
   a polynomial of degree 5 to approximate R. The maximum error
   of this polynomial approximation is bounded by 2**-59. In
   other words,
       R(z) ~ 2.0 + P1*z + P2*z**2 + P3*z**3 + P4*z**4 + P5*z**5
       (where z=r*r, and the values of P1 to P5 are listed below)
   and

       |                  5          |     -59
       | 2.0+P1*z+...+P5*z   -  R(z) | <= 2
       |                             |

   The computation of exp(r) thus becomes
                      2*r
       exp(r) = 1 + -------
                     R - r
                          r*R1(r)
              = 1 + r + ----------- (for better accuracy)
                         2 - R1(r)
   where
                2       4                     10
       R1(r) = r - (P1*r  + P2*r  + ... + P5*r   ).

3. Scale back to obtain exp(x):
   From step 1, we have
   exp(x) = 2^k * exp(r)
Special cases:
exp(INF) is INF, exp(NaN) is NaN;
exp(-INF) is 0, and
for finite argument, only exp(0)=1 is exact.
Accuracy:
according to an error analysis, the error is always less than
1 ulp (unit in the last place).
Misc. info:
For IEEE double
    if x >  7.09782712893383973096e+02 then exp(x) overflow
    if x < -7.45133219101941108420e+02 then exp(x) underflow
Constants:
The hexadecimal values are the intended ones for the following
constants. The decimal values may be used, provided that the
compiler will convert from decimal to binary accurately enough
to produce the hexadecimal values shown.

Definition at line 138 of file exp.c.

References halF, huge, invln2, ln2HI, ln2LO, o_threshold, one, P1, P2, P3, P4, P5, twom1000, and u_threshold.

Referenced by cchsh(), cexp(), cosh(), cpow(), and sinh().

139 {
140  double y, hi, lo, c, t;
141  int32_t k, xsb;
142  uint32_t hx, hy;
143 
144  lo = 0.0;
145  hi = 0.0;
146 
147  GET_HIGH_WORD(hx, x); // high word of x
148  xsb = (hx >> 31) & 1; // sign bit of x
149  hx &= 0x7FFFFFFF; // high word of |x|
150 
151  // filter out non-finite argument
152  // if |x|>=709.78...
153  if (hx >= 0x40862E42)
154  {
155  if (hx >= 0x7FF00000)
156  {
157  uint32_t lx;
158  GET_LOW_WORD(lx, x);
159  if (((hx & 0xFFFFF) | lx) != 0)
160  {
161  return NAN;
162  }
163 
164  // exp(+-inf)={inf,0}
165  return (xsb == 0) ? x : 0.0;
166  }
167 
168  if (x > o_threshold)
169  {
170  // overflow
171  return huge * huge;
172  }
173 
174  if (x < u_threshold)
175  {
176  // underflow
177  return twom1000 * twom1000;
178  }
179  }
180 
181  // argument reduction
182  // |x| > 0.5 ln2
183  if (hx > 0x3FD62E42)
184  {
185  // |x| < 1.5 ln2
186  if (hx < 0x3FF0A2B2)
187  {
188  hi = x - ln2HI[xsb];
189  lo = ln2LO[xsb];
190  k = 1 - xsb - xsb;
191  }
192  else
193  {
194  k = (int32_t)(invln2 * x + halF[xsb]);
195  t = k;
196  hi = x - t * ln2HI[0]; // t*ln2HI is exact here
197  lo = t * ln2LO[0];
198  }
199  x = hi - lo;
200  }
201  // when |x|<2**-28
202  else if (hx < 0x3E300000)
203  {
204  if (huge + x > one)
205  {
206  return one + x; // trigger inexact
207  }
208  else
209  {
210  k = 0;
211  }
212  }
213  else
214  {
215  k = 0;
216  }
217 
218  // x is now in primary range
219  t = x * x;
220  c = x - t * (P1 + t * (P2 + t * (P3 + t * (P4 + t * P5))));
221  if (k == 0)
222  {
223  return one - ((x * c) / (c - 2.0) - x);
224  }
225 
226  y = one - ((lo - (x * c) / (2.0 - c)) - hi);
227 
228  if (k >= -1021)
229  {
230  GET_HIGH_WORD(hy, y);
231  SET_HIGH_WORD(y, hy + (k << 20)); // add k to y's exponent
232  return y;
233  }
234 
235  GET_HIGH_WORD(hy, y);
236  SET_HIGH_WORD(y, hy + ((k + 1000) << 20)); // add k to y's exponent
237  return y * twom1000;
238 }
static const double halF[2]
Definition: exp.c:45
#define GET_HIGH_WORD(i, d)
Get the more significant 32 bit int from a double.
Definition: prim.h:167
static const double u_threshold
Definition: exp.c:50
static const double P2
Definition: exp.c:61
static const double P5
Definition: exp.c:64
#define GET_LOW_WORD(i, d)
Get the less significant 32 bit int from a double.
Definition: prim.h:177
static const double ln2LO[2]
Definition: exp.c:55
static const double ln2HI[2]
Definition: exp.c:51
static const double twom1000
Definition: exp.c:48
static const double one
Definition: exp.c:44
static const double huge
Definition: exp.c:48
static const double P3
Definition: exp.c:62
#define NAN
Definition: mathr.h:53
static const double P1
Definition: exp.c:60
static const double P4
Definition: exp.c:63
static const double o_threshold
Definition: exp.c:49
static const double invln2
Definition: exp.c:59
#define SET_HIGH_WORD(d, v)
Set the more significant 32 bits of a double from an int.
Definition: prim.h:198
Here is the caller graph for this function:

◆ expm1()

double expm1 ( double  x)

Definition at line 153 of file expm1.c.

References huge, invln2, ln2_hi, ln2_lo, o_threshold, one, Q1, Q2, Q3, Q4, Q5, and tiny.

Referenced by cosh(), sinh(), and tanh().

154 {
155  double y, hi, lo, c, t, e, hxs, hfx, r1;
156  int32_t k, xsb;
157  uint32_t hx;
158 
159  c = 0.0;
160 
161  GET_HIGH_WORD(hx, x); /* high word of x */
162  xsb = hx & 0x80000000; /* sign bit of x */
163  hx &= 0x7fffffff; /* high word of |x| */
164 
165  /* filter out huge and non-finite argument */
166  if (hx >= 0x4043687A)
167  { /* if |x|>=56*ln2 */
168  if (hx >= 0x40862E42)
169  { /* if |x|>=709.78... */
170  if (hx >= 0x7ff00000)
171  {
172  uint32_t low;
173  GET_LOW_WORD(low, x);
174  if (((hx & 0xfffff) | low) != 0)
175  return x + x; /* NaN */
176  else
177  return (xsb == 0) ? x : -1.0; /* exp(+-inf)={inf,-1} */
178  }
179  if (x > o_threshold)
180  return huge * huge; /* overflow */
181  }
182  if (xsb != 0)
183  { /* x < -56*ln2, return -1.0 with inexact */
184  if (x + tiny < 0.0) /* raise inexact */
185  return tiny - one; /* return -1 */
186  }
187  }
188 
189  /* argument reduction */
190  if (hx > 0x3fd62e42)
191  { /* if |x| > 0.5 ln2 */
192  if (hx < 0x3FF0A2B2)
193  { /* and |x| < 1.5 ln2 */
194  if (xsb == 0)
195  {
196  hi = x - ln2_hi;
197  lo = ln2_lo;
198  k = 1;
199  }
200  else
201  {
202  hi = x + ln2_hi;
203  lo = -ln2_lo;
204  k = -1;
205  }
206  }
207  else
208  {
209  k = (int32_t)(invln2 * x + ((xsb == 0) ? 0.5 : -0.5));
210  t = k;
211  hi = x - t * ln2_hi; /* t*ln2_hi is exact here */
212  lo = t * ln2_lo;
213  }
214  x = hi - lo;
215  c = (hi - x) - lo;
216  }
217  else if (hx < 0x3c900000)
218  { /* when |x|<2**-54, return x */
219  t = huge + x; /* return x with inexact flags when x!=0 */
220  return x - (t - (huge + x));
221  }
222  else
223  k = 0;
224 
225  /* x is now in primary range */
226  hfx = 0.5 * x;
227  hxs = x * hfx;
228  r1 = one + hxs * (Q1 + hxs * (Q2 + hxs * (Q3 + hxs * (Q4 + hxs * Q5))));
229  t = 3.0 - r1 * hfx;
230  e = hxs * ((r1 - t) / (6.0 - x * t));
231  if (k == 0)
232  return x - (x * e - hxs); /* c is 0 */
233  else
234  {
235  e = (x * (e - c) - c);
236  e -= hxs;
237  if (k == -1)
238  return 0.5 * (x - e) - 0.5;
239  if (k == 1)
240  {
241  if (x < -0.25)
242  return -2.0 * (e - (x + 0.5));
243  else
244  return one + 2.0 * (x - e);
245  }
246  if (k <= -2 || k > 56)
247  { /* suffice to return exp(x)-1 */
248  uint32_t hy;
249 
250  y = one - (e - x);
251  GET_HIGH_WORD(hy, y);
252  SET_HIGH_WORD(y, hy + (k << 20)); /* add k to y's exponent */
253  return y - one;
254  }
255  t = one;
256  if (k < 20)
257  {
258  uint32_t hy;
259 
260  SET_HIGH_WORD(t, 0x3ff00000 - (0x200000 >> k)); /* t=1-2^-k */
261  y = t - (e - x);
262  GET_HIGH_WORD(hy, y);
263  SET_HIGH_WORD(y, hy + (k << 20)); /* add k to y's exponent */
264  }
265  else
266  {
267  uint32_t hy;
268 
269  SET_HIGH_WORD(t, (0x3ff - k) << 20); /* 2^-k */
270  y = x - (e + t);
271  y += one;
272  GET_HIGH_WORD(hy, y);
273  SET_HIGH_WORD(y, hy + (k << 20)); /* add k to y's exponent */
274  }
275  }
276  return y;
277 }
#define GET_HIGH_WORD(i, d)
Get the more significant 32 bit int from a double.
Definition: prim.h:167
static const double tiny
Definition: expm1.c:141
static const double Q5
Definition: expm1.c:151
static const double Q1
Definition: expm1.c:147
#define GET_LOW_WORD(i, d)
Get the less significant 32 bit int from a double.
Definition: prim.h:177
static const double Q2
Definition: expm1.c:148
static const double one
Definition: expm1.c:139
static const double o_threshold
Definition: expm1.c:142
static const double ln2_hi
Definition: expm1.c:143
static const double huge
Definition: expm1.c:140
static const double invln2
Definition: expm1.c:145
static const double ln2_lo
Definition: expm1.c:144
static const double Q4
Definition: expm1.c:150
#define SET_HIGH_WORD(d, v)
Set the more significant 32 bits of a double from an int.
Definition: prim.h:198
static const double Q3
Definition: expm1.c:149
Here is the caller graph for this function:

◆ exs()

double exs ( double  x)

Exsecant function.

exsec(x) = sec(x)-1
         = (1-cos(x))/cos(x)
         = ver(x)/cos(x)
         = ver(x)*sec(x)
         = 2*sin(x/2)*sin(x/2)*sec(x)

Definition at line 48 of file exs.c.

References sec(), and ver().

Referenced by RealNumber::ExSecant().

49 {
50  return ver(x) * sec(x);
51 }
double ver(double x)
Versed sine function.
Definition: ver.c:45
double sec(double x)
Secant function.
Definition: sec.c:45
Here is the call graph for this function:
Here is the caller graph for this function:

◆ fabs()

double fabs ( double  x)

Returns the absolute value of x.

Definition at line 51 of file fabs.c.

Referenced by __kernel_tan(), RealNumber::Absolute(), asin(), asinh(), atan(), atan2(), cchsh(), cosh(), csqrt(), DecimalSystem::GetText(), PositionalNumeralSystem::GetText(), pow(), rempio2(), sinh(), and tanh().

52 {
53  uint32_t hx;
54  GET_HIGH_WORD(hx, x);
55  SET_HIGH_WORD(x, hx & 0x7fffffff);
56  return x;
57 }
#define GET_HIGH_WORD(i, d)
Get the more significant 32 bit int from a double.
Definition: prim.h:167
#define SET_HIGH_WORD(d, v)
Set the more significant 32 bits of a double from an int.
Definition: prim.h:198
Here is the caller graph for this function:

◆ floor()

double floor ( double  x)

Floor function.

Returns
x rounded toward -inf to integral value
Method:
    Bit twiddling
Exception:
    Inexact flag raised if x not equal to floor(x)

Definition at line 62 of file floor.c.

References huge.

Referenced by __kernel_rem_pio2(), cfloor(), RealNumber::Floor(), round(), and trunc().

63 {
64  int32_t i0, i1, j0;
65  uint32_t i, j;
66  EXTRACT_WORDS(i0, i1, x);
67  j0 = ((i0 >> 20) & 0x7ff) - 0x3ff;
68  if (j0 < 20)
69  {
70  if (j0 < 0)
71  { /* raise inexact if x != 0 */
72  if (huge + x > 0.0)
73  { /* return 0*sign(x) if |x|<1 */
74  if (i0 >= 0)
75  {
76  i0 = i1 = 0;
77  }
78  else if (((i0 & 0x7fffffff) | i1) != 0)
79  {
80  i0 = 0xbff00000;
81  i1 = 0;
82  }
83  }
84  }
85  else
86  {
87  i = (0x000fffff) >> j0;
88  if (((i0 & i) | i1) == 0)
89  return x; /* x is integral */
90  if (huge + x > 0.0)
91  { /* raise inexact flag */
92  if (i0 < 0)
93  i0 += (0x00100000) >> j0;
94  i0 &= (~i);
95  i1 = 0;
96  }
97  }
98  }
99  else if (j0 > 51)
100  {
101  if (j0 == 0x400)
102  return x + x; /* inf or NaN */
103  else
104  return x; /* x is integral */
105  }
106  else
107  {
108  i = ((uint32_t)(0xffffffff)) >> (j0 - 20);
109  if ((i1 & i) == 0)
110  return x; /* x is integral */
111  if (huge + x > 0.0)
112  { /* raise inexact flag */
113  if (i0 < 0)
114  {
115  if (j0 == 20)
116  i0 += 1;
117  else
118  {
119  j = i1 + (1 << (52 - j0));
120  if (j < (uint32_t)i1)
121  i0 += 1; /* got a carry */
122  i1 = j;
123  }
124  }
125  i1 &= (~i);
126  }
127  }
128  INSERT_WORDS(x, i0, i1);
129  return x;
130 }
#define INSERT_WORDS(d, ix0, ix1)
Set a double from two 32 bit ints.
Definition: prim.h:187
static const double huge
Definition: floor.c:48
#define EXTRACT_WORDS(ix0, ix1, d)
Get two 32 bit ints from a double.
Definition: prim.h:156
Here is the caller graph for this function:

◆ fmod()

double fmod ( double  x,
double  y 
)

Return x mod y in exact arithmetic.

Method: Shift and subtract

Definition at line 58 of file fmod.c.

References one, and Zero.

Referenced by PositionalNumeralSystem::IntegerToBuffer().

59 {
60  int32_t n, hx, hy, hz, ix, iy, sx, i;
61  uint32_t lx, ly, lz;
62 
63  EXTRACT_WORDS(hx, lx, x);
64  EXTRACT_WORDS(hy, ly, y);
65  sx = hx & 0x80000000; /* sign of x */
66  hx ^= sx; /* |x| */
67  hy &= 0x7fffffff; /* |y| */
68 
69  /* purge off exception values */
70  if ((hy | ly) == 0 || (hx >= 0x7ff00000) || /* y=0,or x not finite */
71  ((hy | ((ly | -ly) >> 31)) > 0x7ff00000)) /* or y is NaN */
72  return (x * y) / (x * y);
73  if (hx <= hy)
74  {
75  if ((hx < hy) || (lx < ly))
76  return x; /* |x|<|y| return x */
77  if (lx == ly)
78  return Zero[(uint32_t)sx >> 31]; /* |x|=|y| return x*0*/
79  }
80 
81  /* determine ix = ilogb(x) */
82  if (hx < 0x00100000)
83  { /* subnormal x */
84  if (hx == 0)
85  {
86  for (ix = -1043, i = lx; i > 0; i <<= 1)
87  ix -= 1;
88  }
89  else
90  {
91  for (ix = -1022, i = (hx << 11); i > 0; i <<= 1)
92  ix -= 1;
93  }
94  }
95  else
96  ix = (hx >> 20) - 1023;
97 
98  /* determine iy = ilogb(y) */
99  if (hy < 0x00100000)
100  { /* subnormal y */
101  if (hy == 0)
102  {
103  for (iy = -1043, i = ly; i > 0; i <<= 1)
104  iy -= 1;
105  }
106  else
107  {
108  for (iy = -1022, i = (hy << 11); i > 0; i <<= 1)
109  iy -= 1;
110  }
111  }
112  else
113  iy = (hy >> 20) - 1023;
114 
115  /* set up {hx,lx}, {hy,ly} and align y to x */
116  if (ix >= -1022)
117  hx = 0x00100000 | (0x000fffff & hx);
118  else
119  { /* subnormal x, shift x to normal */
120  n = -1022 - ix;
121  if (n <= 31)
122  {
123  hx = (hx << n) | (lx >> (32 - n));
124  lx <<= n;
125  }
126  else
127  {
128  hx = lx << (n - 32);
129  lx = 0;
130  }
131  }
132  if (iy >= -1022)
133  hy = 0x00100000 | (0x000fffff & hy);
134  else
135  { /* subnormal y, shift y to normal */
136  n = -1022 - iy;
137  if (n <= 31)
138  {
139  hy = (hy << n) | (ly >> (32 - n));
140  ly <<= n;
141  }
142  else
143  {
144  hy = ly << (n - 32);
145  ly = 0;
146  }
147  }
148 
149  /* fix point fmod */
150  n = ix - iy;
151  while (n--)
152  {
153  hz = hx - hy;
154  lz = lx - ly;
155  if (lx < ly)
156  hz -= 1;
157  if (hz < 0)
158  {
159  hx = hx + hx + (lx >> 31);
160  lx = lx + lx;
161  }
162  else
163  {
164  if ((hz | lz) == 0) /* return sign(x)*0 */
165  return Zero[(uint32_t)sx >> 31];
166  hx = hz + hz + (lz >> 31);
167  lx = lz + lz;
168  }
169  }
170  hz = hx - hy;
171  lz = lx - ly;
172  if (lx < ly)
173  hz -= 1;
174  if (hz >= 0)
175  {
176  hx = hz;
177  lx = lz;
178  }
179 
180  /* convert back to floating value and restore the sign */
181  if ((hx | lx) == 0) /* return sign(x)*0 */
182  return Zero[(unsigned)sx >> 31];
183  while (hx < 0x00100000)
184  { /* normalize x */
185  hx = hx + hx + (lx >> 31);
186  lx = lx + lx;
187  iy -= 1;
188  }
189  if (iy >= -1022)
190  { /* normalize output */
191  hx = ((hx - 0x00100000) | ((iy + 1023) << 20));
192  INSERT_WORDS(x, hx | sx, lx);
193  }
194  else
195  { /* subnormal output */
196  n = -1022 - iy;
197  if (n <= 20)
198  {
199  lx = (lx >> n) | ((uint32_t)hx << (32 - n));
200  hx >>= n;
201  }
202  else if (n <= 31)
203  {
204  lx = (hx << (32 - n)) | (lx >> n);
205  hx = sx;
206  }
207  else
208  {
209  lx = hx >> (n - 32);
210  hx = sx;
211  }
212  INSERT_WORDS(x, hx | sx, lx);
213  x *= one; /* create necessary signal */
214  }
215  return x; /* exact output */
216 }
#define INSERT_WORDS(d, ix0, ix1)
Set a double from two 32 bit ints.
Definition: prim.h:187
static const double Zero[]
Definition: fmod.c:50
#define EXTRACT_WORDS(ix0, ix1, d)
Get two 32 bit ints from a double.
Definition: prim.h:156
static const double one
Definition: fmod.c:49
Here is the caller graph for this function:

◆ hcc()

double hcc ( double  x)

Hacoversed cosine function.

hcc(x) = (1+sin(x))/2

Definition at line 44 of file hcc.c.

References sin().

Referenced by RealNumber::HaCoVerCosine().

45 {
46  double a = sin(x);
47  double b = 1.0 - a;
48  double c = b / 2.0;
49  return c;
50 }
double sin(double x)
Sine function.
Definition: sin.c:86
Here is the call graph for this function:
Here is the caller graph for this function:

◆ hcv()

double hcv ( double  x)

Hacoversed sine function.

hcv(x) = (1-sin(x))/2

Definition at line 44 of file hcv.c.

References sin().

Referenced by RealNumber::HaCoVerSine().

45 {
46  double a = sin(x);
47  double b = 1.0 - a;
48  double c = b / 2.0;
49  return c;
50 }
double sin(double x)
Sine function.
Definition: sin.c:86
Here is the call graph for this function:
Here is the caller graph for this function:

◆ hv()

double hv ( double  x)

Haversed sine function.

hv(x) = (1-cos(x))/2

Definition at line 44 of file hv.c.

References cos().

Referenced by RealNumber::HaVerSine().

45 {
46  double a = cos(x);
47  double b = 1.0 - a;
48  double c = b / 2.0;
49  return c;
50 }
double cos(double x)
Cosine function.
Definition: cos.c:87
Here is the call graph for this function:
Here is the caller graph for this function:

◆ hvc()

double hvc ( double  x)

Haversed cosine function.

hvc(x) = (1+cos(x))/2

Definition at line 44 of file hvc.c.

References cos().

Referenced by RealNumber::HaVerCosine().

45 {
46  double a = cos(x);
47  double b = 1.0 + a;
48  double c = b / 2.0;
49  return c;
50 }
double cos(double x)
Cosine function.
Definition: cos.c:87
Here is the call graph for this function:
Here is the caller graph for this function:

◆ hypot()

double hypot ( double  x,
double  y 
)

hypot

Method
 If (assume round-to-nearest) z=x*x+y*y
 has error less than sqrt(2)/2 ulp, than
 sqrt(z) has error less than 1 ulp (exercise).
 So, compute sqrt(x*x+y*y) with some care as
 follows to get the error below 1 ulp:
 Assume x>y>0;
 (if possible, set rounding to round-to-nearest)
 1. if x > 2y  use
    x1*x1+(y*y+(x2*(x+x1))) for x*x+y*y
 where x1 = x with lower 32 bits cleared, x2 = x-x1; else
 2. if x <= 2y use
    t1*y1+((x-y)*(x-y)+(t1*y2+t2*y))
 where t1 = 2x with lower 32 bits cleared, t2 = 2x-t1,
 y1= y with lower 32 bits chopped, y2 = y-y1.
 NOTE: scaling may be necessary if some argument is too
       large or too tiny
Special cases:
 hypot(x,y) is INF if x or y is +INF or -INF; else
 hypot(x,y) is NAN if x or y is NAN.
Accuracy:
    hypot(x,y) returns sqrt(x^2+y^2) with error less
    than 1 ulps (units in the last place)

Definition at line 81 of file hypot.c.

References sqrt().

Referenced by cabs().

82 {
83  double a = x, b = y, t1, t2, y1, y2, w;
84  uint32_t j, k, ha, hb, hx, hy;
85 
86  GET_HIGH_WORD(hx, x);
87  GET_HIGH_WORD(hy, y);
88  ha = hx & 0x7FFFFFFF; // high word of x
89  hb = hy & 0x7FFFFFFF; // high word of y
90 
91  if (hb > ha)
92  {
93  a = y;
94  b = x;
95  j = ha;
96  ha = hb;
97  hb = j;
98  }
99  else
100  {
101  a = x;
102  b = y;
103  }
104 
105  SET_HIGH_WORD(a, ha); // a <- |a|
106  SET_HIGH_WORD(b, hb); // b <- |b|
107 
108  // x/y > 2**60
109  if ((ha - hb) > 0x3C00000)
110  {
111  return a + b;
112  }
113 
114  k = 0;
115 
116  // a>2**500
117  if (ha > 0x5F300000)
118  {
119  // Inf or NaN
120  if (ha >= 0x7FF00000)
121  {
122  uint32_t la, lb;
123  w = a + b; // for sNaN
124  GET_LOW_WORD(la, a);
125  GET_LOW_WORD(lb, b);
126 
127  if (((ha & 0xFFFFF) | la) == 0)
128  {
129  w = a;
130  }
131 
132  if (((hb ^ 0x7FF00000) | lb) == 0)
133  {
134  w = b;
135  }
136 
137  return w;
138  }
139 
140  // scale a and b by 2**-600
141  ha -= 0x25800000;
142  hb -= 0x25800000;
143  k += 600;
144  SET_HIGH_WORD(a, ha);
145  SET_HIGH_WORD(b, hb);
146  }
147 
148  // b < 2**-500
149  if (hb < 0x20B00000)
150  {
151  // subnormal b or 0
152  if (hb <= 0x000FFFFF)
153  {
154  uint32_t lb;
155  GET_LOW_WORD(lb, b);
156  if ((hb | lb) == 0)
157  {
158  return a;
159  }
160 
161  t1 = 0;
162  SET_HIGH_WORD(t1, 0x7FD00000); /* t1=2^1022 */
163  b *= t1;
164  a *= t1;
165  k -= 1022;
166  }
167  else
168  { /* scale a and b by 2^600 */
169  ha += 0x25800000; /* a *= 2^600 */
170  hb += 0x25800000; /* b *= 2^600 */
171  k -= 600;
172 
173  SET_HIGH_WORD(a, ha);
174  SET_HIGH_WORD(b, hb);
175  }
176  }
177 
178  // medium size a and b
179  w = a - b;
180  if (w > b)
181  {
182  t1 = 0;
183  SET_HIGH_WORD(t1, ha);
184  t2 = a - t1;
185  w = sqrt(t1 * t1 - (b * (-b) - t2 * (a + t1)));
186  }
187  else
188  {
189  a = a + a;
190  y1 = 0;
191  SET_HIGH_WORD(y1, hb);
192  y2 = b - y1;
193  t1 = 0;
194  SET_HIGH_WORD(t1, ha + 0x00100000);
195  t2 = a - t1;
196  w = sqrt(t1 * y1 - (w * (-w) - (t1 * y2 + t2 * b)));
197  }
198 
199  if (k != 0)
200  {
201  uint32_t ht1;
202  t1 = 1.0;
203  GET_HIGH_WORD(ht1, t1);
204  SET_HIGH_WORD(t1, ht1 + (k << 20));
205  return t1 * w;
206  }
207 
208  return w;
209 }
#define GET_HIGH_WORD(i, d)
Get the more significant 32 bit int from a double.
Definition: prim.h:167
#define GET_LOW_WORD(i, d)
Get the less significant 32 bit int from a double.
Definition: prim.h:177
double sqrt(double x)
Square root function.
Definition: sqrt.c:119
#define SET_HIGH_WORD(d, v)
Set the more significant 32 bits of a double from an int.
Definition: prim.h:198
Here is the call graph for this function:
Here is the caller graph for this function:

◆ log()

double log ( double  x)

Natural logarithm function (base e)

Method
  1. Argument Reduction: find k and f such that
        x = 2^k * (1+f),
    where  sqrt(2)/2 < 1+f < sqrt(2) .
  2. Approximation of log(1+f).
 Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s)
     = 2s + 2/3 s**3 + 2/5 s**5 + .....,
         = 2s + s*R
     We use a special Remes algorithm on [0,0.1716] to generate
    a polynomial of degree 14 to approximate R The maximum error
 of this polynomial approximation is bounded by 2**-58.45. In
 other words,
            2      4      6      8      10      12      14
     R(z) ~ Lg1*s +Lg2*s +Lg3*s +Lg4*s +Lg5*s  +Lg6*s  +Lg7*s
    (the values of Lg1 to Lg7 are listed in the program)
 and
     |      2          14          |     -58.45
     | Lg1*s +...+Lg7*s    -  R(z) | <= 2
     |                             |
 Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2.
 In order to guarantee error in log below 1ulp, we compute log
 by
    log(1+f) = f - s*(f - R)    (if f is not too large)
    log(1+f) = f - (hfsq - s*(hfsq+R)). (better accuracy)
 3. Finally,  log(x) = k*ln2 + log(1+f).
            = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo)))
    Here ln2 is split into two floating point number:
        ln2_hi + ln2_lo,
    where n*ln2_hi is always exact for |n| < 2000.
Special cases:
 log(x) is NaN with signal if x < 0 (including -INF) ;
 log(+INF) is +INF; log(0) is -INF with signal;
 log(NaN) is that NaN with no signal.
Accuracy:
 according to an error analysis, the error is always less than
 1 ulp (unit in the last place).
Constants:
The hexadecimal values are the intended ones for the following
constants. The decimal values may be used, provided that the
compiler will convert from decimal to binary accurately enough
to produce the hexadecimal values shown.

Definition at line 109 of file log.c.

References Lg1, Lg2, Lg3, Lg4, Lg5, Lg6, Lg7, ln2_hi, ln2_lo, two54, and zero.

Referenced by acosh(), acoth(), acsch(), asech(), asinh(), clog(), cpow(), RealNumber::Log(), log10(), RealNumber::Log2(), and log2p().

110 {
111  double hfsq,f,s,z,R,w,t1,t2,dk;
112  int32_t k,hx,i,j;
113  uint32_t lx;
114 
115  EXTRACT_WORDS(hx,lx,x);
116 
117  k=0;
118  if (hx < 0x00100000) { /* x < 2**-1022 */
119  if (((hx&0x7fffffff)|lx)==0)
120  return -two54/zero; /* log(+-0)=-inf */
121  if (hx<0) return (x-x)/zero; /* log(-#) = NaN */
122  k -= 54;
123  x *= two54; /* subnormal number, scale up x */
124  GET_HIGH_WORD(hx,x); /* high word of x */
125  }
126  if (hx >= 0x7ff00000) return x+x;
127  k += (hx>>20)-1023;
128  hx &= 0x000fffff;
129  i = (hx+0x95f64)&0x100000;
130  SET_HIGH_WORD(x,hx|(i^0x3ff00000)); /* normalize x or x/2 */
131  k += (i>>20);
132  f = x-1.0;
133  if((0x000fffff&(2+hx))<3) { /* |f| < 2**-20 */
134  if(f==zero) {
135  if(k==0)
136  return zero;
137  else {
138  dk=(double)k;
139  return dk*ln2_hi+dk*ln2_lo;
140  }
141  }
142  R = f*f*(0.5-0.33333333333333333*f);
143  if(k==0) return f-R;
144  else {
145  dk=(double)k;
146  return dk*ln2_hi-((R-dk*ln2_lo)-f);
147  }
148  }
149  s = f/(2.0+f);
150  dk = (double)k;
151  z = s*s;
152  i = hx-0x6147a;
153  w = z*z;
154  j = 0x6b851-hx;
155  t1= w*(Lg2+w*(Lg4+w*Lg6));
156  t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
157  i |= j;
158  R = t2+t1;
159  if(i>0) {
160  hfsq=0.5*f*f;
161  if(k==0) return f-(hfsq-s*(hfsq+R));
162  else
163  return dk*ln2_hi-((hfsq-(s*(hfsq+R)+dk*ln2_lo))-f);
164  } else {
165  if(k==0) return f-s*(f-R);
166  else
167  return dk*ln2_hi-((s*(f-R)-dk*ln2_lo)-f);
168  }
169 }
static const double Lg7
Definition: log.c:53
static const double Lg6
Definition: log.c:52
#define GET_HIGH_WORD(i, d)
Get the more significant 32 bit int from a double.
Definition: prim.h:167
static const double two54
Definition: log.c:46
static const double Lg2
Definition: log.c:48
#define EXTRACT_WORDS(ix0, ix1, d)
Get two 32 bit ints from a double.
Definition: prim.h:156
static double zero
Definition: log.c:55
static const double Lg3
Definition: log.c:49
static const double ln2_hi
Definition: log.c:44
static const double Lg4
Definition: log.c:50
static const double Lg1
Definition: log.c:47
#define SET_HIGH_WORD(d, v)
Set the more significant 32 bits of a double from an int.
Definition: prim.h:198
static const double ln2_lo
Definition: log.c:45
static const double Lg5
Definition: log.c:51
Here is the caller graph for this function:

◆ log10()

double log10 ( double  x)

Base 10 logarithm function.

Method:
Let log10_2hi = leading 40 bits of log10(2) and
    log10_2lo = log10(2) - log10_2hi,
    ivln10    = 1/log(10) rounded.
Then
    n = ilogb(x),
    if(n<0)  n = n+1;
    x = scalbn(x,-n);
    log10(x) := n*log10_2hi + (n*log10_2lo + ivln10*log(x))

Note 1:
To guarantee log10(10**n)=n, where 10**n is normal, the rounding
mode must set to Round-to-Nearest.

Note 2:
[1/log(10)] rounded to 53 bits has error .198 ulps;
log10 is monotonic at all binary break points.
Special cases:
log10(x) is NaN with signal if x < 0;
log10(+INF) is +INF with no signal; log10(0) is -INF with signal;
log10(NaN) is that NaN with no signal;
log10(10**N) = N  for N=0,1,...,22.
Constants:
The hexadecimal values are the intended ones for the following constants.
The decimal values may be used, provided that the compiler will convert
from decimal to binary accurately enough to produce the hexadecimal values
shown.

Definition at line 93 of file log10.c.

References ivln10, log(), log10_2hi, log10_2lo, two54, and zero.

Referenced by DecimalSystem::GetText(), and RealNumber::Log10().

94 {
95  double y,z;
96  int32_t i,k,hx;
97  uint32_t lx;
98 
99  EXTRACT_WORDS(hx,lx,x);
100 
101  k=0;
102  if (hx < 0x00100000) { /* x < 2**-1022 */
103  if (((hx&0x7fffffff)|lx)==0)
104  return -two54/zero; /* log(+-0)=-inf */
105  if (hx<0) return (x-x)/zero; /* log(-#) = NaN */
106  k -= 54;
107  x *= two54; /* subnormal number, scale up x */
108  GET_HIGH_WORD(hx, x); /* high word of x */
109  }
110  if (hx >= 0x7ff00000) return x+x;
111  k += (hx>>20)-1023;
112  i = ((uint32_t)k&0x80000000)>>31;
113  hx = (hx&0x000fffff)|((0x3ff-i)<<20);
114  y = (double)(k+i);
115  SET_HIGH_WORD(x,hx);
116  z = y*log10_2lo + ivln10*log(x);
117  return z+y*log10_2hi;
118 }
static double zero
Definition: log10.c:54
#define GET_HIGH_WORD(i, d)
Get the more significant 32 bit int from a double.
Definition: prim.h:167
#define EXTRACT_WORDS(ix0, ix1, d)
Get two 32 bit ints from a double.
Definition: prim.h:156
static const double two54
Definition: log10.c:49
static const double log10_2hi
Definition: log10.c:51
static const double ivln10
Definition: log10.c:50
#define SET_HIGH_WORD(d, v)
Set the more significant 32 bits of a double from an int.
Definition: prim.h:198
double log(double x)
Natural logarithm function (base e)
Definition: log.c:109
static const double log10_2lo
Definition: log10.c:52
Here is the call graph for this function:
Here is the caller graph for this function:

◆ log1p()

double log1p ( double  x)

Definition at line 122 of file log1p.c.

References ln2_hi, ln2_lo, Lp1, Lp2, Lp3, Lp4, Lp5, Lp6, Lp7, two54, and zero.

Referenced by acosh(), asinh(), and atanh().

123 {
124  double hfsq,f,c,s,z,R,u;
125  int32_t k,hx,hu,ax;
126 
127  f = 0.0;
128  c = 0.0;
129  hu = 0;
130 
131  GET_HIGH_WORD(hx,x); /* high word of x */
132  ax = hx&0x7fffffff;
133 
134  k = 1;
135  if (hx < 0x3FDA827A) { /* x < 0.41422 */
136  if(ax>=0x3ff00000) { /* x <= -1.0 */
137  if(x==-1.0) return -two54/zero; /* log1p(-1)=+inf */
138  else return (x-x)/(x-x); /* log1p(x<-1)=NaN */
139  }
140  if(ax<0x3e200000) { /* |x| < 2**-29 */
141  if(two54+x>zero /* raise inexact */
142  &&ax<0x3c900000) /* |x| < 2**-54 */
143  return x;
144  else
145  return x - x*x*0.5;
146  }
147  if(hx>0||hx<=((int)0xbfd2bec3)) {
148  k=0;
149  f=x;
150  hu=1;
151  } /* -0.2929<x<0.41422 */
152  }
153  if (hx >= 0x7ff00000) return x+x;
154  if(k!=0) {
155  if(hx<0x43400000) {
156  u = 1.0+x;
157  GET_HIGH_WORD(hu,u); /* high word of u */
158  k = (hu>>20)-1023;
159  c = (k>0)? 1.0-(u-x):x-(u-1.0);/* correction term */
160  c /= u;
161  } else {
162  u = x;
163  GET_HIGH_WORD(hu,u); /* high word of u */
164  k = (hu>>20)-1023;
165  c = 0;
166  }
167  hu &= 0x000fffff;
168  if(hu<0x6a09e) {
169  SET_HIGH_WORD(u, hu|0x3ff00000); /* normalize u */
170  } else {
171  k += 1;
172  SET_HIGH_WORD(u, hu|0x3fe00000); /* normalize u/2 */
173  hu = (0x00100000-hu)>>2;
174  }
175  f = u-1.0;
176  }
177  hfsq=0.5*f*f;
178  if(hu==0) { /* |f| < 2**-20 */
179  if(f==zero) {
180  if(k==0) return zero;
181  else {
182  c += k*ln2_lo;
183  return k*ln2_hi+c;
184  }
185  }
186  R = hfsq*(1.0-0.66666666666666666*f);
187  if(k==0) return f-R;
188  else
189  return k*ln2_hi-((R-(k*ln2_lo+c))-f);
190  }
191  s = f/(2.0+f);
192  z = s*s;
193  R = z*(Lp1+z*(Lp2+z*(Lp3+z*(Lp4+z*(Lp5+z*(Lp6+z*Lp7))))));
194  if(k==0) return f-(hfsq-s*(hfsq+R));
195  else
196  return k*ln2_hi-((hfsq-(s*(hfsq+R)+(k*ln2_lo+c)))-f);
197 }
static const double Lp6
Definition: log1p.c:117
static double zero
Definition: log1p.c:120
#define GET_HIGH_WORD(i, d)
Get the more significant 32 bit int from a double.
Definition: prim.h:167
static const double Lp4
Definition: log1p.c:115
static const double ln2_lo
Definition: log1p.c:110
static const double Lp3
Definition: log1p.c:114
static const double Lp5
Definition: log1p.c:116
static const double two54
Definition: log1p.c:111
static const double Lp2
Definition: log1p.c:113
static const double ln2_hi
Definition: log1p.c:109
static const double Lp7
Definition: log1p.c:118
static const double Lp1
Definition: log1p.c:112
#define SET_HIGH_WORD(d, v)
Set the more significant 32 bits of a double from an int.
Definition: prim.h:198
Here is the caller graph for this function:

◆ log2i()

unsigned int log2i ( unsigned int  x)

Referenced by Dragon4(), and DecimalSystem::GetText().

Here is the caller graph for this function:

◆ log2p()

double log2p ( double  x,
double  y 
)

Definition at line 32 of file log2p.c.

References log().

Referenced by PositionalNumeralSystem::GetText().

33 {
34  return y != 1.0
35  ? log(y) / log(x)
36  : 0.0;
37 }
double log(double x)
Natural logarithm function (base e)
Definition: log.c:109
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pow()

double pow ( double  x,
double  y 
)

Expontation function.

Method:  Let x =  2   * (1+f)
 1. Compute and return log2(x) in two pieces:
    log2(x) = w1 + w2,
    where w1 has 53-24 = 29 bit trailing zeros.
 2. Perform y*log2(x) = n+y' by simulating muti-precision
    arithmetic, where |y'|<=0.5.
 3. Return x**y = 2**n*exp(y'*log2)
Special cases:
 1.  (anything) ** 0  is 1
 2.  (anything) ** 1  is itself
 3.  (anything) ** NAN is NAN
 4.  NAN ** (anything except 0) is NAN
 5.  +-(|x| > 1) **  +INF is +INF
 6.  +-(|x| > 1) **  -INF is +0
 7.  +-(|x| < 1) **  +INF is +0
 8.  +-(|x| < 1) **  -INF is +INF
 9.  +-1         ** +-INF is NAN
 10. +0 ** (+anything except 0, NAN)               is +0
 11. -0 ** (+anything except 0, NAN, odd integer)  is +0
 12. +0 ** (-anything except 0, NAN)               is +INF
 13. -0 ** (-anything except 0, NAN, odd integer)  is +INF
 14. -0 ** (odd integer) = -( +0 ** (odd integer) )
 15. +INF ** (+anything except 0,NAN) is +INF
 16. +INF ** (-anything except 0,NAN) is +0
 17. -INF ** (anything)  = -0 ** (-anything)
 18. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer)
 19. (-anything except 0 and inf) ** (non-integer) is NAN
Accuracy:
 pow(x,y) returns x**y nearly rounded. In particular
        pow(integer,integer)
 always returns the correct integer provided it is
 representable.
Constants :
The hexadecimal values are the intended ones for the following
constants. The decimal values may be used, provided that the
compiler will convert from decimal to binary accurately enough
to produce the hexadecimal values shown.

Definition at line 138 of file pow.c.

References bp, cp, cp_h, cp_l, dp_h, dp_l, fabs(), huge, ivln2, ivln2_h, ivln2_l, L1, L2, L3, L4, L5, L6, lg2, lg2_h, lg2_l, one, ovt, P1, P2, P3, P4, P5, scalbn(), sqrt(), tiny, two, two53, and zero.

Referenced by cpow(), PositionalNumeralSystem::GetText(), PositionalNumeralSystem::Parse(), and RealNumber::Raise().

139 {
140  double z, ax, z_h, z_l, p_h, p_l;
141  double y1, t1, t2, r, s, t, u, v, w;
142  int32_t i, j, k, yisint, n;
143  int32_t hx, hy, ix, iy;
144  uint32_t lx, ly;
145 
146  EXTRACT_WORDS(hx, lx, x);
147  EXTRACT_WORDS(hy, ly, y);
148  ix = hx & 0x7fffffff;
149  iy = hy & 0x7fffffff;
150 
151  /* y==zero: x**0 = 1 */
152  if ((iy | ly) == 0)
153  return one;
154 
155  /* +-NaN return x+y */
156  if (ix > 0x7ff00000 || ((ix == 0x7ff00000) && (lx != 0)) ||
157  iy > 0x7ff00000 || ((iy == 0x7ff00000) && (ly != 0)))
158  return x + y;
159 
160  /* determine if y is an odd int when x < 0
161  * yisint = 0 ... y is not an integer
162  * yisint = 1 ... y is an odd int
163  * yisint = 2 ... y is an even int
164  */
165  yisint = 0;
166  if (hx < 0)
167  {
168  if (iy >= 0x43400000)
169  yisint = 2; /* even integer y */
170  else if (iy >= 0x3ff00000)
171  {
172  k = (iy >> 20) - 0x3ff; /* exponent */
173  if (k > 20)
174  {
175  j = ly >> (52 - k);
176  if ((uint32_t)(j << (52 - k)) == ly)
177  yisint = 2 - (j & 1);
178  }
179  else if (ly == 0)
180  {
181  j = iy >> (20 - k);
182  if ((j << (20 - k)) == iy)
183  yisint = 2 - (j & 1);
184  }
185  }
186  }
187 
188  /* special value of y */
189  if (ly == 0)
190  {
191  if (iy == 0x7ff00000)
192  { /* y is +-inf */
193  if (((ix - 0x3ff00000) | lx) == 0)
194  return y - y; /* inf**+-1 is NaN */
195  else if (ix >= 0x3ff00000) /* (|x|>1)**+-inf = inf,0 */
196  return (hy >= 0) ? y : zero;
197  else /* (|x|<1)**-,+inf = inf,0 */
198  return (hy < 0) ? -y : zero;
199  }
200  if (iy == 0x3ff00000)
201  { /* y is +-1 */
202  if (hy < 0)
203  return one / x;
204  else
205  return x;
206  }
207  if (hy == 0x40000000)
208  return x * x; /* y is 2 */
209  if (hy == 0x3fe00000)
210  { /* y is 0.5 */
211  if (hx >= 0) /* x >= +0 */
212  return sqrt(x);
213  }
214  }
215 
216  ax = fabs(x);
217  /* special value of x */
218  if (lx == 0)
219  {
220  if (ix == 0x7ff00000 || ix == 0 || ix == 0x3ff00000)
221  {
222  z = ax; /*x is +-0,+-inf,+-1*/
223  if (hy < 0)
224  z = one / z; /* z = (1/|x|) */
225  if (hx < 0)
226  {
227  if (((ix - 0x3ff00000) | yisint) == 0)
228  {
229  z = (z - z) / (z - z); /* (-1)**non-int is NaN */
230  }
231  else if (yisint == 1)
232  z = -z; /* (x<0)**odd = -(|x|**odd) */
233  }
234  return z;
235  }
236  }
237 
238  n = (hx >> 31) + 1;
239 
240  /* (x<0)**(non-int) is NaN */
241  if ((n | yisint) == 0)
242  return (x - x) / (x - x);
243 
244  s = one; /* s (sign of result -ve**odd) = -1 else = 1 */
245  if ((n | (yisint - 1)) == 0)
246  s = -one; /* (-ve)**(odd int) */
247 
248  /* |y| is huge */
249  if (iy > 0x41e00000)
250  { /* if |y| > 2**31 */
251  if (iy > 0x43f00000)
252  { /* if |y| > 2**64, must o/uflow */
253  if (ix <= 0x3fefffff)
254  return (hy < 0) ? huge * huge : tiny * tiny;
255  if (ix >= 0x3ff00000)
256  return (hy > 0) ? huge * huge : tiny * tiny;
257  }
258  /* over/underflow if x is not close to one */
259  if (ix < 0x3fefffff)
260  return (hy < 0) ? s * huge * huge : s * tiny * tiny;
261  if (ix > 0x3ff00000)
262  return (hy > 0) ? s * huge * huge : s * tiny * tiny;
263  /* now |1-x| is tiny <= 2**-20, suffice to compute
264  log(x) by x-x^2/2+x^3/3-x^4/4 */
265  t = ax - one; /* t has 20 trailing zeros */
266  w = (t * t) * (0.5 - t * (0.3333333333333333333333 - t * 0.25));
267  u = ivln2_h * t; /* ivln2_h has 21 sig. bits */
268  v = t * ivln2_l - w * ivln2;
269  t1 = u + v;
270  SET_LOW_WORD(t1, 0);
271  t2 = v - (t1 - u);
272  }
273  else
274  {
275  double ss, s2, s_h, s_l, t_h, t_l;
276  n = 0;
277  /* take care subnormal number */
278  if (ix < 0x00100000)
279  {
280  ax *= two53;
281  n -= 53;
282  GET_HIGH_WORD(ix, ax);
283  }
284  n += ((ix) >> 20) - 0x3ff;
285  j = ix & 0x000fffff;
286  /* determine interval */
287  ix = j | 0x3ff00000; /* normalize ix */
288  if (j <= 0x3988E)
289  k = 0; /* |x|<sqrt(3/2) */
290  else if (j < 0xBB67A)
291  k = 1; /* |x|<sqrt(3) */
292  else
293  {
294  k = 0;
295  n += 1;
296  ix -= 0x00100000;
297  }
298  SET_HIGH_WORD(ax, ix);
299 
300  /* compute ss = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
301  u = ax - bp[k]; /* bp[0]=1.0, bp[1]=1.5 */
302  v = one / (ax + bp[k]);
303  ss = u * v;
304  s_h = ss;
305  SET_LOW_WORD(s_h, 0);
306  /* t_h=ax+bp[k] High */
307  t_h = zero;
308  SET_HIGH_WORD(t_h, ((ix >> 1) | 0x20000000) + 0x00080000 + (k << 18));
309  t_l = ax - (t_h - bp[k]);
310  s_l = v * ((u - s_h * t_h) - s_h * t_l);
311  /* compute log(ax) */
312  s2 = ss * ss;
313  r = s2 * s2 * (L1 + s2 * (L2 + s2 * (L3 + s2 * (L4 + s2 * (L5 + s2 * L6)))));
314  r += s_l * (s_h + ss);
315  s2 = s_h * s_h;
316  t_h = 3.0 + s2 + r;
317  SET_LOW_WORD(t_h, 0);
318  t_l = r - ((t_h - 3.0) - s2);
319  /* u+v = ss*(1+...) */
320  u = s_h * t_h;
321  v = s_l * t_h + t_l * ss;
322  /* 2/(3log2)*(ss+...) */
323  p_h = u + v;
324  SET_LOW_WORD(p_h, 0);
325  p_l = v - (p_h - u);
326  z_h = cp_h * p_h; /* cp_h+cp_l = 2/(3*log2) */
327  z_l = cp_l * p_h + p_l * cp + dp_l[k];
328  /* log2(ax) = (ss+..)*2/(3*log2) = n + dp_h + z_h + z_l */
329  t = (double)n;
330  t1 = (((z_h + z_l) + dp_h[k]) + t);
331  SET_LOW_WORD(t1, 0);
332  t2 = z_l - (((t1 - t) - dp_h[k]) - z_h);
333  }
334 
335  /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
336  y1 = y;
337  SET_LOW_WORD(y1, 0);
338  p_l = (y - y1) * t1 + y * t2;
339  p_h = y1 * t1;
340  z = p_l + p_h;
341  EXTRACT_WORDS(j, i, z);
342  if (j >= 0x40900000)
343  { /* z >= 1024 */
344  if (((j - 0x40900000) | i) != 0) /* if z > 1024 */
345  return s * huge * huge; /* overflow */
346  else
347  {
348  if (p_l + ovt > z - p_h)
349  return s * huge * huge; /* overflow */
350  }
351  }
352  else if ((j & 0x7fffffff) >= 0x4090cc00)
353  { /* z <= -1075 */
354  if (((j - 0xc090cc00) | i) != 0) /* z < -1075 */
355  return s * tiny * tiny; /* underflow */
356  else
357  {
358  if (p_l <= z - p_h)
359  return s * tiny * tiny; /* underflow */
360  }
361  }
362  /*
363  * compute 2**(p_h+p_l)
364  */
365  i = j & 0x7fffffff;
366  k = (i >> 20) - 0x3ff;
367  n = 0;
368  if (i > 0x3fe00000)
369  { /* if |z| > 0.5, set n = [z+0.5] */
370  n = j + (0x00100000 >> (k + 1));
371  k = ((n & 0x7fffffff) >> 20) - 0x3ff; /* new k for n */
372  t = zero;
373  SET_HIGH_WORD(t, (n & ~(0x000fffff >> k)));
374  n = ((n & 0x000fffff) | 0x00100000) >> (20 - k);
375  if (j < 0)
376  n = -n;
377  p_h -= t;
378  }
379  t = p_l + p_h;
380  SET_LOW_WORD(t, 0);
381  u = t * lg2_h;
382  v = (p_l - (t - p_h)) * lg2 + t * lg2_l;
383  z = u + v;
384  w = v - (z - u);
385  t = z * z;
386  t1 = z - t * (P1 + t * (P2 + t * (P3 + t * (P4 + t * P5))));
387  r = (z * t1) / (t1 - two) - (w + z * w);
388  z = one - (r - z);
389  GET_HIGH_WORD(j, z);
390  j += (n << 20);
391  if ((j >> 20) <= 0)
392  z = scalbn(z, n); /* subnormal output */
393  else
394  {
395  uint32_t hz;
396  GET_HIGH_WORD(hz, z);
397  SET_HIGH_WORD(z, hz + (n << 20));
398  }
399  return s * z;
400 }
static const double cp_l
Definition: pow.c:87
static const double L6
Definition: pow.c:75
#define GET_HIGH_WORD(i, d)
Get the more significant 32 bit int from a double.
Definition: prim.h:167
static const double lg2_h
Definition: pow.c:82
static const double dp_h[]
Definition: pow.c:60
static const double ivln2_h
Definition: pow.c:89
static const double two53
Definition: pow.c:67
static const double P2
Definition: pow.c:77
static const double P1
Definition: pow.c:76
static const double huge
Definition: pow.c:68
static const double one
Definition: pow.c:67
#define EXTRACT_WORDS(ix0, ix1, d)
Get two 32 bit ints from a double.
Definition: prim.h:156
static const double ivln2_l
Definition: pow.c:90
static const double P3
Definition: pow.c:78
static const double ivln2
Definition: pow.c:88
static const double lg2
Definition: pow.c:81
static const double L3
Definition: pow.c:72
static const double zero
Definition: pow.c:66
double scalbn(double x, int n)
static const double ovt
Definition: pow.c:84
static const double dp_l[]
Definition: pow.c:63
static const double P4
Definition: pow.c:79
static const double L1
Definition: pow.c:70
static const double L5
Definition: pow.c:74
static const double cp_h
Definition: pow.c:86
static const double lg2_l
Definition: pow.c:83
static const double tiny
Definition: pow.c:68
static const double two
Definition: pow.c:67
#define SET_LOW_WORD(d, v)
Set the less significant 32 bits of a double from an int.
Definition: prim.h:209
static const double L4
Definition: pow.c:73
static const double L2
Definition: pow.c:71
static const double cp
Definition: pow.c:85
double sqrt(double x)
Square root function.
Definition: sqrt.c:119
#define SET_HIGH_WORD(d, v)
Set the more significant 32 bits of a double from an int.
Definition: prim.h:198
double fabs(double x)
Returns the absolute value of x.
Definition: fabs.c:51
static const double bp[]
Definition: pow.c:57
static const double P5
Definition: pow.c:80
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rempio2()

int rempio2 ( double  x,
double *  y 
)

Definition at line 104 of file remp2.c.

References __kernel_rem_pio2(), fabs(), half, invpio2, npio2_hw, pio2_1, pio2_1t, pio2_2, pio2_2t, pio2_3, pio2_3t, two24, two_over_pi, and zero.

Referenced by cos(), sin(), and tan().

105 {
106  double z = 0.,w,t,r,fn;
107  double tx[3];
108  int32_t i,j,n,ix,hx;
109  int e0,nx;
110  uint32_t low;
111 
112  GET_HIGH_WORD(hx,x); /* high word of x */
113  ix = hx&0x7fffffff;
114  if(ix<=0x3fe921fb) /* |x| ~<= pi/4 , no need for reduction */
115  {
116  y[0] = x;
117  y[1] = 0;
118  return 0;
119  }
120  if(ix<0x4002d97c) { /* |x| < 3pi/4, special case with n=+-1 */
121  if(hx>0) {
122  z = x - pio2_1;
123  if(ix!=0x3ff921fb) { /* 33+53 bit pi is good enough */
124  y[0] = z - pio2_1t;
125  y[1] = (z-y[0])-pio2_1t;
126  } else { /* near pi/2, use 33+33+53 bit pi */
127  z -= pio2_2;
128  y[0] = z - pio2_2t;
129  y[1] = (z-y[0])-pio2_2t;
130  }
131  return 1;
132  } else { /* negative x */
133  z = x + pio2_1;
134  if(ix!=0x3ff921fb) { /* 33+53 bit pi is good enough */
135  y[0] = z + pio2_1t;
136  y[1] = (z-y[0])+pio2_1t;
137  } else { /* near pi/2, use 33+33+53 bit pi */
138  z += pio2_2;
139  y[0] = z + pio2_2t;
140  y[1] = (z-y[0])+pio2_2t;
141  }
142  return -1;
143  }
144  }
145  if(ix<=0x413921fb) { /* |x| ~<= 2^19*(pi/2), medium size */
146  t = fabs(x);
147  n = (int32_t) (t*invpio2+half);
148  fn = (double)n;
149  r = t-fn*pio2_1;
150  w = fn*pio2_1t; /* 1st round good to 85 bit */
151  if(n<32&&ix!=npio2_hw[n-1]) {
152  y[0] = r-w; /* quick check no cancellation */
153  } else {
154  uint32_t high;
155 
156  j = ix>>20;
157  y[0] = r-w;
158  GET_HIGH_WORD(high, y[0]);
159  i = j-((high>>20)&0x7ff);
160  if(i>16) { /* 2nd iteration needed, good to 118 */
161  t = r;
162  w = fn*pio2_2;
163  r = t-w;
164  w = fn*pio2_2t-((t-r)-w);
165  y[0] = r-w;
166  GET_HIGH_WORD(high,y[0]);
167  i = j-((high>>20)&0x7ff);
168  if(i>49) { /* 3rd iteration need, 151 bits acc */
169  t = r; /* will cover all possible cases */
170  w = fn*pio2_3;
171  r = t-w;
172  w = fn*pio2_3t-((t-r)-w);
173  y[0] = r-w;
174  }
175  }
176  }
177  y[1] = (r-y[0])-w;
178  if(hx<0) {
179  y[0] = -y[0];
180  y[1] = -y[1];
181  return -n;
182  }
183  else return n;
184  }
185  /*
186  * all other (large) arguments
187  */
188  if(ix>=0x7ff00000) { /* x is inf or NaN */
189  y[0]=y[1]=x-x;
190  return 0;
191  }
192  /* set z = scalbn(|x|,ilogb(x)-23) */
193  GET_LOW_WORD(low,x);
194  SET_LOW_WORD(z,low);
195  e0 = (int32_t)(ix>>20)-1046; /* e0 = ilogb(z)-23; */
196  SET_HIGH_WORD(z,ix - (e0<<20));
197  for(i=0; i<2; i++) {
198  tx[i] = (double)((int32_t)(z));
199  z = (z-tx[i])*two24;
200  }
201  tx[2] = z;
202  nx = 3;
203  while(tx[nx-1]==zero) nx--; /* skip zero term */
204  n = __kernel_rem_pio2(tx,y,e0,nx,2,two_over_pi);
205  if(hx<0) {
206  y[0] = -y[0];
207  y[1] = -y[1];
208  return -n;
209  }
210  return n;
211 }
static const double pio2_3
Definition: remp2.c:101
#define GET_HIGH_WORD(i, d)
Get the more significant 32 bit int from a double.
Definition: prim.h:167
static const double zero
Definition: remp2.c:93
static const double half
Definition: remp2.c:94
static const double pio2_2t
Definition: remp2.c:100
#define GET_LOW_WORD(i, d)
Get the less significant 32 bit int from a double.
Definition: prim.h:177
static const double pio2_1t
Definition: remp2.c:98
static const double pio2_1
Definition: remp2.c:97
int __kernel_rem_pio2(double *x, double *y, int e0, int nx, int prec, const int *ipio2)
Kernel reduction function.
Definition: kremp2.c:184
static const double invpio2
Definition: remp2.c:96
static const int two_over_pi[]
Definition: remp2.c:59
static const double two24
Definition: remp2.c:95
static const double pio2_2
Definition: remp2.c:99
static const int npio2_hw[]
Definition: remp2.c:73
#define SET_LOW_WORD(d, v)
Set the less significant 32 bits of a double from an int.
Definition: prim.h:209
#define SET_HIGH_WORD(d, v)
Set the more significant 32 bits of a double from an int.
Definition: prim.h:198
double fabs(double x)
Returns the absolute value of x.
Definition: fabs.c:51
static const double pio2_3t
Definition: remp2.c:102
Here is the call graph for this function:
Here is the caller graph for this function:

◆ round()

double round ( double  x)

Round function.

Definition at line 40 of file round.c.

References ceil(), and floor().

Referenced by cround(), PositionalNumeralSystem::GetText(), and RealNumber::Round().

41 {
42  return x > 0.0
43  ? floor(x + 0.5)
44  : ceil(x - 0.5);
45 }
double ceil(double x)
Ceiling function.
Definition: ceil.c:63
double floor(double x)
Floor function.
Definition: floor.c:62
Here is the call graph for this function:
Here is the caller graph for this function:

◆ scalbn()

double scalbn ( double  x,
int  n 
)

◆ sec()

double sec ( double  x)

Secant function.

sec(x) = 1/cos(x)
       = 1/sqrt(cos(x)*cos(x))

Definition at line 45 of file sec.c.

References cos(), and sqrt().

Referenced by exs(), and RealNumber::Secant().

46 {
47  double a, b, c;
48 
49  a = cos(x);
50  if (a == 0.0)
51  {
52  return NAN;
53  }
54 
55  b = sqrt(a * a);
56  c = 1.0 / b;
57 
58  return c;
59 }
double cos(double x)
Cosine function.
Definition: cos.c:87
#define NAN
Definition: mathr.h:53
double sqrt(double x)
Square root function.
Definition: sqrt.c:119
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sech()

double sech ( double  x)

Hyperbolic secant function.

sech(x) = 1/cosh(x)

Definition at line 44 of file sech.c.

References cosh().

Referenced by RealNumber::HypSecant().

45 {
46  double a = cosh(x);
47  if (TRIG_INEXACT(a))
48  {
49  return NAN;
50  }
51  return 1.0 / a;
52 }
double cosh(double x)
Hyperbolic cosine function.
Definition: cosh.c:83
#define TRIG_INEXACT(x)
Definition: prim.h:48
#define NAN
Definition: mathr.h:53
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sin()

double sin ( double  x)

Sine function.

Returns
Sine function of x
Kernel function:
__kernel_sin        ... sine function on [-pi/4,pi/4]
__kernel_cos        ... cose function on [-pi/4,pi/4]
__ieee754_rem_pio2  ... argument reduction routine
Method:
Let S,C and T denote the sin, cos and tan respectively on
[-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
in [-pi/4 , +pi/4], and let n = k mod 4.

We have

     n        sin(x)      cos(x)        tan(x)
----------------------------------------------------------
     0          S           C             T
     1          C          -S           -1/T
     2         -S          -C             T
     3         -C           S           -1/T
----------------------------------------------------------
Special cases:
Let trig be any of sin, cos, or tan.
trig(+-INF)  is NaN
trig(NaN)    is that NaN
Accuracy:
TRIG(x) returns trig(x) nearly rounded

Definition at line 86 of file sin.c.

References __kernel_cos(), __kernel_sin(), and rempio2().

Referenced by ccos(), ccosh(), ccot(), ccoth(), ccsc(), ccsch(), cexp(), cot(), cpow(), crd(), csc(), csec(), csech(), csin(), csinh(), ctan(), ctanh(), cvc(), cvs(), hcc(), hcv(), RealNumber::Sine(), and ver().

87 {
88  double y[2], z = 0.0;
89  int32_t n, ix;
90 
91  GET_HIGH_WORD(ix, x);
92  ix &= 0x7FFFFFFF;
93 
94  // |x| ~< pi/4
95  if (ix <= 0x3FE921FB)
96  {
97  return __kernel_sin(x, z, 0);
98  }
99 
100  // sin(Inf or NaN) is NaN
101  if (ix >= 0x7FF00000)
102  {
103  return NAN;
104  }
105 
106  // argument reduction needed
107  n = rempio2(x, y);
108  switch (n & 3)
109  {
110  case 0:
111  return __kernel_sin(y[0], y[1], 1);
112  case 1:
113  return __kernel_cos(y[0], y[1]);
114  case 2:
115  return -__kernel_sin(y[0], y[1], 1);
116  default:
117  return -__kernel_cos(y[0], y[1]);
118  }
119 }
#define GET_HIGH_WORD(i, d)
Get the more significant 32 bit int from a double.
Definition: prim.h:167
double __kernel_cos(double x, double y)
Kernel cosine function.
Definition: kcos.c:94
#define NAN
Definition: mathr.h:53
int rempio2(double x, double *y)
Definition: remp2.c:104
double __kernel_sin(double x, double y, int iy)
Kernel sin function.
Definition: ksin.c:89
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sinh()

double sinh ( double  x)

Hyperbolic sine function.

Method
mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2
 1. Replace x by |x| (sinh(-x) = -sinh(x)).
 2.
                                        E + E/(E+1)
     0        <= x <= 22     :  sinh(x) := -----------—, E=expm1(x)
                                2
     22       <= x <= lnovft :  sinh(x) := exp(x)/2
     lnovft   <= x <= ln2ovft:  sinh(x) := exp(x/2)/2 * exp(x/2)
     ln2ovft  <  x      :  sinh(x) := x*shuge (overflow)
Special cases
    sinh(x) is |x| if x is +INF, -INF, or NaN.
    only sinh(0)=0 is exact for finite x.

Definition at line 77 of file sinh.c.

References exp(), expm1(), fabs(), one, and shuge.

Referenced by cchsh(), ccot(), ccoth(), ccsc(), ccsch(), coth(), csch(), csec(), csech(), ctan(), ctanh(), and RealNumber::HypSine().

78 {
79  double t, w, h;
80  int32_t ix, jx;
81  uint32_t lx;
82 
83  // High word of |x|
84  GET_HIGH_WORD(jx, x);
85  ix = jx & 0x7FFFFFFF;
86 
87  // x is INF or NaN
88  if (ix >= 0x7FF00000)
89  {
90  return NAN;
91  }
92 
93  h = 0.5;
94  if (jx < 0)
95  h = -h;
96  /* |x| in [0,22], return sign(x)*0.5*(E+E/(E+1))) */
97  if (ix < 0x40360000)
98  { /* |x|<22 */
99  if (ix < 0x3E300000) /* |x|<2**-28 */
100  if (shuge + x > one)
101  return x; /* sinh(tiny) = tiny with inexact */
102  t = expm1(fabs(x));
103  if (ix < 0x3FF00000)
104  return h * (2.0 * t - t * t / (t + one));
105  return h * (t + t / (t + one));
106  }
107 
108  /* |x| in [22, log(maxdouble)] return 0.5*exp(|x|) */
109  if (ix < 0x40862E42)
110  return h * exp(fabs(x));
111 
112  /* |x| in [log(maxdouble), overflowthresold] */
113  lx = *((((*(uint32_t *)&one) >> 29)) + (uint32_t *)&x);
114  if (ix < 0x408633CE || ((ix == 0x408633CE) && (lx <= (uint32_t)0X8FB9F87D)))
115  {
116  w = exp(0.5 * fabs(x));
117  t = h * w;
118  return t * w;
119  }
120 
121  /* |x| > overflowthresold, sinh(x) overflow */
122  return x * shuge;
123 }
static const double one
Definition: sinh.c:53
#define GET_HIGH_WORD(i, d)
Get the more significant 32 bit int from a double.
Definition: prim.h:167
#define NAN
Definition: mathr.h:53
static const double shuge
Definition: sinh.c:54
double exp(double x)
Returns the exponential of x.
Definition: exp.c:138
double expm1(double x)
Definition: expm1.c:153
double fabs(double x)
Returns the absolute value of x.
Definition: fabs.c:51
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sqrt()

double sqrt ( double  x)

Square root function.

Returns
Correctly rounded sqrt
Method:
  Bit by bit method using integer arithmetic. (Slow, but portable)
  1. Normalization
     Scale x to y in [1,4) with even powers of 2:
     find an integer k such that  1 <= (y=x*2^(2k)) < 4, then
     sqrt(x) = 2^k * sqrt(y)
  2. Bit by bit computation
     Let q  = sqrt(y) truncated to i bit after binary point (q = 1),
          i                          0
                                    i+1         2
         s  = 2*q , and y  =  2   * ( y - q  ).     (1)
          i      i            i                 i
     To compute q    from q , one checks whether
        i+1       i
  -(i+1) 2
(q + 2 ) <= y. (2) i -(i+1) If (2) is false, then q = q ; otherwise q = q + 2 . i+1 i i+1 i
     With some algebric manipulation, it is not difficult to see
     that (2) is equivalent to
                            -(i+1)
        s  +  2       <= y          (3)
         i                i
     The advantage of (3) is that s  and y  can be computed by
                  i      i
     the following recurrence formula:
         if (3) is false
         s     =  s  ,  y    = y   ;            (4)
          i+1      i         i+1    i
         otherwise,
                        -i                     -(i+1)
         s    =  s  + 2  ,  y    = y  -  s  - 2         (5)
          i+1      i          i+1    i     i
     One may easily use induction to prove (4) and (5).
     Note. Since the left hand side of (3) contain only i+2 bits,
         it does not necessary to do a full (53-bit) comparison
         in (3).
  3. Final rounding
     After generating the 53 bits result, we compute one more bit.
     Together with the remainder, we can decide whether the
     result is exact, bigger than 1/2ulp, or less than 1/2ulp
     (it will never equal to 1/2ulp).
     The rounding mode can be detected by checking whether
     huge + tiny is equal to huge, and whether huge - tiny is
     equal to huge for some floating point number "huge" and "tiny".
Special cases:
  sqrt(+-0) = +-0    ... exact
  sqrt(inf) = inf
  sqrt(-ve) = NaN    ... with invalid signal
  sqrt(NaN) = NaN    ... with invalid signal for signaling NaN

Definition at line 119 of file sqrt.c.

References one, and tiny.

Referenced by acos(), acosh(), acsch(), acvs(), aexs(), ahv(), ahvc(), asech(), asin(), asinh(), aver(), csqrt(), hypot(), pow(), sec(), and RealNumber::SquareRoot().

120 {
121  double z;
122  int32_t sign = (int32_t)0x80000000;
123  uint32_t r, t1, s1, ix1, q1;
124  int32_t ix0, s0, q, m, t, i;
125 
126  EXTRACT_WORDS(ix0, ix1, x);
127 
128  // take care of Inf and NaN
129  if ((ix0 & 0x7FF00000) == 0x7FF00000)
130  {
131  // sqrt(NaN)=NaN
132  // sqrt(+inf)=+inf
133  // sqrt(-inf)=sNaN
134  return x * x + x;
135  }
136 
137  // take care of zero
138  if (ix0 <= 0)
139  {
140  if (((ix0 & (~sign)) | ix1) == 0)
141  {
142  // sqrt(+-0) = +-0
143  return x;
144  }
145  else if (ix0 < 0)
146  {
147  //sqrt(-ve) = NaN
148  return NAN;
149  }
150  }
151 
152  // normalize x
153  m = (ix0 >> 20);
154  if (m == 0)
155  {
156  // subnormal x
157  while (ix0 == 0)
158  {
159  m -= 21;
160  ix0 |= (ix1 >> 11);
161  ix1 <<= 21;
162  }
163 
164  for (i = 0; (ix0 & 0x00100000) == 0; i++)
165  {
166  ix0 <<= 1;
167  }
168 
169  m -= i - 1;
170  ix0 |= (ix1 >> (32 - i));
171  ix1 <<= i;
172  }
173 
174  m -= 1023; // unbias exponent
175  ix0 = (ix0 & 0x000FFFFF) | 0x00100000;
176  if (m & 1)
177  {
178  // odd m, double x to make it even
179  ix0 += ix0 + ((ix1 & sign) >> 31);
180  ix1 += ix1;
181  }
182 
183  // m = [m/2]
184  m >>= 1;
185 
186  // generate sqrt(x) bit by bit
187  ix0 += ix0 + ((ix1 & sign) >> 31);
188  ix1 += ix1;
189  q = q1 = s0 = s1 = 0; // [q,q1] = sqrt(x)
190  r = 0x00200000; // r = moving bit from right to left
191 
192  while (r != 0)
193  {
194  t = s0 + r;
195  if (t <= ix0)
196  {
197  s0 = t + r;
198  ix0 -= t;
199  q += r;
200  }
201  ix0 += ix0 + ((ix1 & sign) >> 31);
202  ix1 += ix1;
203  r >>= 1;
204  }
205 
206  r = sign;
207  while (r != 0)
208  {
209  t1 = s1 + r;
210  t = s0;
211  if ((t < ix0) || ((t == ix0) && (t1 <= ix1)))
212  {
213  s1 = t1 + r;
214  if (((t1 & sign) == (uint32_t)sign) && (s1 & sign) == 0)
215  {
216  s0 += 1;
217  }
218  ix0 -= t;
219  if (ix1 < t1)
220  {
221  ix0 -= 1;
222  }
223  ix1 -= t1;
224  q1 += r;
225  }
226 
227  ix0 += ix0 + ((ix1 & sign) >> 31);
228  ix1 += ix1;
229  r >>= 1;
230  }
231 
232  // use floating add to find out rounding direction
233  if ((ix0 | ix1) != 0)
234  {
235  // trigger inexact flag
236  z = one - tiny;
237  if (z >= one)
238  {
239  z = one + tiny;
240  if (q1 == (uint32_t)0xFFFFFFFF)
241  {
242  q1 = 0;
243  q += 1;
244  }
245  else if (z > one)
246  {
247  if (q1 == (uint32_t)0xFFFFFFFE)
248  {
249  q += 1;
250  }
251  q1 += 2;
252  }
253  else
254  {
255  q1 += (q1 & 1);
256  }
257  }
258  }
259 
260  ix0 = (q >> 1) + 0x3FE00000;
261  ix1 = q1 >> 1;
262  if ((q & 1) == 1)
263  {
264  ix1 |= sign;
265  }
266 
267  ix0 += (m << 20);
268  INSERT_WORDS(z, ix0, ix1);
269 
270  return z;
271 }
#define INSERT_WORDS(d, ix0, ix1)
Set a double from two 32 bit ints.
Definition: prim.h:187
static const double tiny
Definition: sqrt.c:50
#define EXTRACT_WORDS(ix0, ix1, d)
Get two 32 bit ints from a double.
Definition: prim.h:156
static const double one
Definition: sqrt.c:49
#define NAN
Definition: mathr.h:53
Here is the caller graph for this function:

◆ tan()

double tan ( double  x)

Tangent function.

Returns
Tangent function of x
Kernel function:
__kernel_sin        ... sine function on [-pi/4,pi/4]
__kernel_cos        ... cose function on [-pi/4,pi/4]
__ieee754_rem_pio2  ... argument reduction routine
Method:
Let S,C and T denote the sin, cos and tan respectively on
[-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
in [-pi/4 , +pi/4], and let n = k mod 4.

We have

     n        sin(x)      cos(x)        tan(x)
----------------------------------------------------------
     0          S           C             T
     1          C          -S           -1/T
     2         -S          -C             T
     3         -C           S           -1/T
----------------------------------------------------------
Special cases:
Let trig be any of sin, cos, or tan.
trig(+-INF)  is NaN
trig(NaN)    is that NaN
Accuracy:
TRIG(x) returns trig(x) nearly rounded

Definition at line 87 of file tan.c.

References __kernel_tan(), and rempio2().

Referenced by RealNumber::Tangent().

88 {
89  double y[2], z = 0.0;
90  int32_t n, ix;
91 
92  GET_HIGH_WORD(ix, x);
93  ix &= 0x7FFFFFFF;
94 
95  // |x| ~< pi/4
96  if (ix <= 0x3FE921FB)
97  {
98  return __kernel_tan(x, z, 1);
99  }
100 
101  // tan(Inf or NaN) is NaN
102  if (ix >= 0x7FF00000)
103  {
104  return NAN;
105  }
106 
107  // |x| ~< pi/4
108  n = rempio2(x, y);
109  return __kernel_tan(y[0], y[1], 1 - ((n & 1) << 1));
110 }
#define GET_HIGH_WORD(i, d)
Get the more significant 32 bit int from a double.
Definition: prim.h:167
#define NAN
Definition: mathr.h:53
int rempio2(double x, double *y)
Definition: remp2.c:104
double __kernel_tan(double x, double y, int iy)
Kernel tan function.
Definition: ktan.c:108
Here is the call graph for this function:
Here is the caller graph for this function:

◆ tanh()

double tanh ( double  x)

Hyperbolic tangent function.

Returns
The Hyperbolic Tangent of x
Method
                                   x    -x
                                  e  - e
    0. tanh(x) is defined to be --------—
                                   x    -x
                                  e  + e
    1. reduce x to non-negative by tanh(-x) = -tanh(x)
    2.  0      <= x <= 2**-55 : tanh(x) = x*(one+x)
                                           -t
        2**-55 <  x <=  1     : tanh(x) = --—; t = expm1(-2x)
                                          t + 2
                                                2
        1      <= x <=  22.0  : tanh(x) = 1-  --— ; t=expm1(2x)
                                              t + 2
        22.0   <  x <= INF    : tanh(x) = 1
Special cases
    tanh(NaN) is NaN
    only tanh(0)=0 is exact for finite argument.

Definition at line 81 of file tanh.c.

References expm1(), fabs(), one, tiny, and two.

Referenced by RealNumber::HypTangent().

82 {
83  double t, z;
84  int32_t jx, ix;
85 
86  /* High word of |x|. */
87  GET_HIGH_WORD(jx, x);
88  ix = jx & 0x7FFFFFFF;
89 
90  /* x is INF or NaN */
91  if (ix >= 0x7FF00000)
92  {
93  if (jx >= 0)
94  return one / x + one; /* tanh(+-inf)=+-1 */
95  else
96  return NAN; /* tanh(NaN) = NaN */
97  }
98 
99  /* |x| < 22 */
100  if (ix < 0x40360000)
101  { /* |x|<22 */
102  if (ix < 0x3C800000) /* |x|<2**-55 */
103  return x * (one + x); /* tanh(small) = small */
104  if (ix >= 0x3FF00000)
105  { /* |x|>=1 */
106  t = expm1(two * fabs(x));
107  z = one - two / (t + two);
108  }
109  else
110  {
111  t = expm1(-two * fabs(x));
112  z = -t / (t + two);
113  }
114  }
115  /* |x| > 22, return +-1 */
116  else
117  {
118  z = one - tiny; /* raised inexact flag */
119  }
120 
121  return (jx >= 0) ? z : -z;
122 }
static const double tiny
Definition: tanh.c:51
#define GET_HIGH_WORD(i, d)
Get the more significant 32 bit int from a double.
Definition: prim.h:167
static const double one
Definition: tanh.c:49
#define NAN
Definition: mathr.h:53
double expm1(double x)
Definition: expm1.c:153
static const double two
Definition: tanh.c:50
double fabs(double x)
Returns the absolute value of x.
Definition: fabs.c:51
Here is the call graph for this function:
Here is the caller graph for this function:

◆ trunc()

double trunc ( double  x)

Truncate function.

when x > 0
trunc(0)   = floor(x)
when x < 0
trunc(x)   = ceil(x)
Special case
trunc(0)   = 0
trunc(NaN) = NaN

Definition at line 52 of file trunc.c.

References ceil(), and floor().

Referenced by ctrunc(), DecimalSystem::GetText(), PositionalNumeralSystem::GetText(), PositionalNumeralSystem::IntegerToBuffer(), and RealNumber::Trunc().

53 {
54  uint32_t hx, lx;
55  GET_HIGH_WORD(hx, x);
56  if ((hx & 0x7FF00000) == 0x7FF00000)
57  {
58  return NAN;
59  }
60 
61  GET_LOW_WORD(lx, x);
62  if (hx == 0 && lx == 0)
63  {
64  return 0.0;
65  }
66 
67  if ((hx & 0x80000000) != 0x80000000)
68  {
69  return floor(x);
70  }
71 
72  return ceil(x);
73 }
#define GET_HIGH_WORD(i, d)
Get the more significant 32 bit int from a double.
Definition: prim.h:167
double ceil(double x)
Ceiling function.
Definition: ceil.c:63
#define GET_LOW_WORD(i, d)
Get the less significant 32 bit int from a double.
Definition: prim.h:177
#define NAN
Definition: mathr.h:53
double floor(double x)
Floor function.
Definition: floor.c:62
Here is the call graph for this function:
Here is the caller graph for this function:

◆ vcs()

double vcs ( double  x)

Versed cosine function.

vercos = 1+cos(x)
       = 2*cos(x/2)*cos(x/2)

Definition at line 45 of file vcs.c.

References cos().

Referenced by RealNumber::VerCosine().

46 {
47  double a = x / 2.0;
48  double b = cos(a);
49  double c = 2 * b * b;
50  return c;
51 }
double cos(double x)
Cosine function.
Definition: cos.c:87
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ver()

double ver ( double  x)

Versed sine function.

versin = 1-cos(x)
       = 2*sin(x/2)*sin(x/2)

Definition at line 45 of file ver.c.

References sin().

Referenced by exs(), and RealNumber::VerSine().

46 {
47  double a = x / 2.0;
48  double b = sin(a);
49  double c = 2 * b * b;
50  return c;
51 }
double sin(double x)
Sine function.
Definition: sin.c:86
Here is the call graph for this function:
Here is the caller graph for this function: