Print this page


Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libm/common/C/expm1.c
          +++ new/usr/src/lib/libm/common/C/expm1.c
↓ open down ↓ 152 lines elided ↑ open up ↑
 153  153  #define ln2_lo          xxx[5]
 154  154  #define invln2          xxx[6]
 155  155  #define Q1              xxx[7]
 156  156  #define Q2              xxx[8]
 157  157  #define Q3              xxx[9]
 158  158  #define Q4              xxx[10]
 159  159  #define Q5              xxx[11]
 160  160  
 161  161  double
 162  162  expm1(double x) {
 163      -        double y, hi, lo, c, t, e, hxs, hfx, r1;
      163 +        double y, hi, lo, c = 0.0L, t, e, hxs, hfx, r1;
 164  164          int k, xsb;
 165  165          unsigned hx;
 166  166  
 167  167          hx = ((unsigned *) &x)[HIWORD];         /* high word of x */
 168  168          xsb = hx & 0x80000000;                  /* sign bit of x */
 169  169          if (xsb == 0)
 170  170                  y = x;
 171  171          else
 172  172                  y = -x;                         /* y = |x| */
 173  173          hx &= 0x7fffffff;                       /* high word of |x| */
 174  174  
 175      -        /* filter out huge and non-finite arugment */
 176      -        if (hx >= 0x4043687A) {                 /* if |x|>=56*ln2 */
 177      -                if (hx >= 0x40862E42) {         /* if |x|>=709.78... */
      175 +        /* filter out huge and non-finite argument */
      176 +        /* for example exp(38)-1 is approximately 3.1855932e+16 */
      177 +        if (hx >= 0x4043687A) {                 /* if |x|>=56*ln2  (~38.8162...)*/
      178 +                if (hx >= 0x40862E42) {         /* if |x|>=709.78... -> inf */
 178  179                          if (hx >= 0x7ff00000) {
 179  180                                  if (((hx & 0xfffff) | ((int *) &x)[LOWORD])
 180  181                                          != 0)
 181  182                                          return x * x;   /* + -> * for Cheetah */
 182  183                                  else
 183  184                                          return xsb == 0 ? x : -1.0;     /* exp(+-inf)={inf,-1} */
 184  185                          }
 185  186                          if (x > o_threshold)
 186  187                                  return huge * huge;     /* overflow */
 187  188                  }
 188  189                  if (xsb != 0) {         /* x < -56*ln2, return -1.0 w/inexact */
 189  190                          if (x + tiny < 0.0)             /* raise inexact */
 190  191                                  return tiny - one;      /* return -1 */
 191  192                  }
 192  193          }
 193  194  
 194  195          /* argument reduction */
 195  196          if (hx > 0x3fd62e42) {                  /* if  |x| > 0.5 ln2 */
 196  197                  if (hx < 0x3FF0A2B2) {          /* and |x| < 1.5 ln2 */
 197      -                        if (xsb == 0) {
      198 +                        if (xsb == 0) {         /* positive number */
 198  199                                  hi = x - ln2_hi;
 199  200                                  lo = ln2_lo;
 200  201                                  k = 1;
 201  202                          }
 202      -                        else {
      203 +                        else { /* negative number */
 203  204                                  hi = x + ln2_hi;
 204  205                                  lo = -ln2_lo;
 205  206                                  k = -1;
 206  207                          }
 207  208                  }
 208      -                else {
      209 +                else {  /* |x| > 1.5 ln2 */
 209  210                          k = (int) (invln2 * x + (xsb == 0 ? 0.5 : -0.5));
 210  211                          t = k;
 211  212                          hi = x - t * ln2_hi;    /* t*ln2_hi is exact here */
 212  213                          lo = t * ln2_lo;
 213  214                  }
 214  215                  x = hi - lo;
 215      -                c = (hi - x) - lo;
      216 +                c = (hi - x) - lo; /* still at |x| > 0.5 ln2 */
 216  217          }
 217  218          else if (hx < 0x3c900000) {             /* when |x|<2**-54, return x */
 218  219                  t = huge + x;           /* return x w/inexact when x != 0 */
 219  220                  return x - (t - (huge + x));
 220  221          }
 221      -        else
      222 +        else    /* |x| <= 0.5 ln2 */
 222  223                  k = 0;
 223  224  
 224  225          /* x is now in primary range */
 225  226          hfx = 0.5 * x;
 226  227          hxs = x * hfx;
 227  228          r1 = one + hxs * (Q1 + hxs * (Q2 + hxs * (Q3 + hxs * (Q4 + hxs * Q5))));
 228  229          t = 3.0 - r1 * hfx;
 229  230          e = hxs * ((r1 - t) / (6.0 - x * t));
 230      -        if (k == 0)
 231      -                return x - (x * e - hxs);       /* c is 0 */
 232      -        else {
      231 +        if (k == 0) /* |x| <= 0.5 ln2 */
      232 +                return x - (x * e - hxs);
      233 +        else {      /* |x| > 0.5 ln2 */
 233  234                  e = (x * (e - c) - c);
 234  235                  e -= hxs;
 235  236                  if (k == -1)
 236  237                          return 0.5 * (x - e) - 0.5;
 237      -                if (k == 1)
      238 +                if (k == 1) {
 238  239                          if (x < -0.25)
 239  240                                  return -2.0 * (e - (x + 0.5));
 240  241                          else
 241  242                                  return one + 2.0 * (x - e);
      243 +                }
 242  244                  if (k <= -2 || k > 56) {        /* suffice to return exp(x)-1 */
 243  245                          y = one - (e - x);
 244  246                          ((int *) &y)[HIWORD] += k << 20;
 245  247                          return y - one;
 246  248                  }
 247  249                  t = one;
 248  250                  if (k < 20) {
 249  251                          ((int *) &t)[HIWORD] = 0x3ff00000 - (0x200000 >> k);
 250  252                                                          /* t = 1 - 2^-k */
 251  253                          y = t - (e - x);
↓ open down ↓ 11 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX