OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libquadmath/] [math/] [expm1q.c] - Blame information for rev 841

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 740 jeremybenn
/*                                                      expm1l.c
2
 *
3
 *      Exponential function, minus 1
4
 *      128-bit __float128 precision
5
 *
6
 *
7
 *
8
 * SYNOPSIS:
9
 *
10
 * __float128 x, y, expm1l();
11
 *
12
 * y = expm1l( x );
13
 *
14
 *
15
 *
16
 * DESCRIPTION:
17
 *
18
 * Returns e (2.71828...) raised to the x power, minus one.
19
 *
20
 * Range reduction is accomplished by separating the argument
21
 * into an integer k and fraction f such that
22
 *
23
 *     x    k  f
24
 *    e  = 2  e.
25
 *
26
 * An expansion x + .5 x^2 + x^3 R(x) approximates exp(f) - 1
27
 * in the basic range [-0.5 ln 2, 0.5 ln 2].
28
 *
29
 *
30
 * ACCURACY:
31
 *
32
 *                      Relative error:
33
 * arithmetic   domain     # trials      peak         rms
34
 *    IEEE    -79,+MAXLOG    100,000     1.7e-34     4.5e-35
35
 *
36
 */
37
 
38
/* Copyright 2001 by Stephen L. Moshier
39
 
40
    This library is free software; you can redistribute it and/or
41
    modify it under the terms of the GNU Lesser General Public
42
    License as published by the Free Software Foundation; either
43
    version 2.1 of the License, or (at your option) any later version.
44
 
45
    This library is distributed in the hope that it will be useful,
46
    but WITHOUT ANY WARRANTY; without even the implied warranty of
47
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
48
    Lesser General Public License for more details.
49
 
50
    You should have received a copy of the GNU Lesser General Public
51
    License along with this library; if not, write to the Free Software
52
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA */
53
 
54
 
55
 
56
#include "quadmath-imp.h"
57
 
58
/* exp(x) - 1 = x + 0.5 x^2 + x^3 P(x)/Q(x)
59
   -.5 ln 2  <  x  <  .5 ln 2
60
   Theoretical peak relative error = 8.1e-36  */
61
 
62
static const __float128
63
  P0 = 2.943520915569954073888921213330863757240E8Q,
64
  P1 = -5.722847283900608941516165725053359168840E7Q,
65
  P2 = 8.944630806357575461578107295909719817253E6Q,
66
  P3 = -7.212432713558031519943281748462837065308E5Q,
67
  P4 = 4.578962475841642634225390068461943438441E4Q,
68
  P5 = -1.716772506388927649032068540558788106762E3Q,
69
  P6 = 4.401308817383362136048032038528753151144E1Q,
70
  P7 = -4.888737542888633647784737721812546636240E-1Q,
71
  Q0 = 1.766112549341972444333352727998584753865E9Q,
72
  Q1 = -7.848989743695296475743081255027098295771E8Q,
73
  Q2 = 1.615869009634292424463780387327037251069E8Q,
74
  Q3 = -2.019684072836541751428967854947019415698E7Q,
75
  Q4 = 1.682912729190313538934190635536631941751E6Q,
76
  Q5 = -9.615511549171441430850103489315371768998E4Q,
77
  Q6 = 3.697714952261803935521187272204485251835E3Q,
78
  Q7 = -8.802340681794263968892934703309274564037E1Q,
79
  /* Q8 = 1.000000000000000000000000000000000000000E0 */
80
/* C1 + C2 = ln 2 */
81
 
82
  C1 = 6.93145751953125E-1Q,
83
  C2 = 1.428606820309417232121458176568075500134E-6Q,
84
/* ln (2^16384 * (1 - 2^-113)) */
85
  maxlog = 1.1356523406294143949491931077970764891253E4Q,
86
/* ln 2^-114 */
87
  minarg = -7.9018778583833765273564461846232128760607E1Q;
88
 
89
 
90
__float128
91
expm1q (__float128 x)
92
{
93
  __float128 px, qx, xx;
94
  int32_t ix, sign;
95
  ieee854_float128 u;
96
  int k;
97
 
98
  /* Detect infinity and NaN.  */
99
  u.value = x;
100
  ix = u.words32.w0;
101
  sign = ix & 0x80000000;
102
  ix &= 0x7fffffff;
103
  if (ix >= 0x7fff0000)
104
    {
105
      /* Infinity. */
106
      if (((ix & 0xffff) | u.words32.w1 | u.words32.w2 | u.words32.w3) == 0)
107
        {
108
          if (sign)
109
            return -1.0Q;
110
          else
111
            return x;
112
        }
113
      /* NaN. No invalid exception. */
114
      return x;
115
    }
116
 
117
  /* expm1(+- 0) = +- 0.  */
118
  if ((ix == 0) && (u.words32.w1 | u.words32.w2 | u.words32.w3) == 0)
119
    return x;
120
 
121
  /* Overflow.  */
122
  if (x > maxlog)
123
    return (HUGE_VALQ * HUGE_VALQ);
124
 
125
  /* Minimum value.  */
126
  if (x < minarg)
127
    return (4.0/HUGE_VALQ - 1.0Q);
128
 
129
  /* Express x = ln 2 (k + remainder), remainder not exceeding 1/2. */
130
  xx = C1 + C2;                 /* ln 2. */
131
  px = floorq (0.5 + x / xx);
132
  k = px;
133
  /* remainder times ln 2 */
134
  x -= px * C1;
135
  x -= px * C2;
136
 
137
  /* Approximate exp(remainder ln 2).  */
138
  px = (((((((P7 * x
139
              + P6) * x
140
             + P5) * x + P4) * x + P3) * x + P2) * x + P1) * x + P0) * x;
141
 
142
  qx = (((((((x
143
              + Q7) * x
144
             + Q6) * x + Q5) * x + Q4) * x + Q3) * x + Q2) * x + Q1) * x + Q0;
145
 
146
  xx = x * x;
147
  qx = x + (0.5 * xx + xx * px / qx);
148
 
149
  /* exp(x) = exp(k ln 2) exp(remainder ln 2) = 2^k exp(remainder ln 2).
150
 
151
  We have qx = exp(remainder ln 2) - 1, so
152
  exp(x) - 1 = 2^k (qx + 1) - 1
153
             = 2^k qx + 2^k - 1.  */
154
 
155
  px = ldexpq (1.0Q, k);
156
  x = px * qx + (px - 1.0);
157
  return x;
158
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.