Print this page
11210 libm should be cstyle(1ONBLD) clean

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libm/common/C/log1p.c
          +++ new/usr/src/lib/libm/common/C/log1p.c
↓ open down ↓ 10 lines elided ↑ open up ↑
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
       21 +
  21   22  /*
  22   23   * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  23   24   */
       25 +
  24   26  /*
  25   27   * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  26   28   * Use is subject to license terms.
  27   29   */
  28   30  
  29   31  #pragma weak __log1p = log1p
  30   32  
  31      -/* INDENT OFF */
       33 +
  32   34  /*
  33   35   * Method :
  34   36   *   1. Argument Reduction: find k and f such that
  35   37   *                      1+x = 2^k * (1+f),
  36   38   *         where  sqrt(2)/2 < 1+f < sqrt(2) .
  37   39   *
  38   40   *      Note. If k=0, then f=x is exact. However, if k != 0, then f
  39   41   *      may not be representable exactly. In that case, a correction
  40   42   *      term is need. Let u=1+x rounded. Let c = (1+x)-u, then
  41   43   *      log(1+x) - log(u) ~ c/u. Thus, we proceed to compute log(u),
  42   44   *      and add back the correction term c/u.
  43   45   *      (Note: when x > 2**53, one can simply return log(x))
  44   46   *
  45   47   *   2. Approximation of log1p(f).
  46   48   *      Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s)
  47   49   *               = 2s + 2/3 s**3 + 2/5 s**5 + .....,
  48   50   *               = 2s + s*R
  49   51   *      We use a special Reme algorithm on [0,0.1716] to generate
  50      - *      a polynomial of degree 14 to approximate R The maximum error
       52 + *      a polynomial of degree 14 to approximate R The maximum error
  51   53   *      of this polynomial approximation is bounded by 2**-58.45. In
  52   54   *      other words,
  53   55   *                      2      4      6      8      10      12      14
  54   56   *          R(z) ~ Lp1*s +Lp2*s +Lp3*s +Lp4*s +Lp5*s  +Lp6*s  +Lp7*s
  55      - *      (the values of Lp1 to Lp7 are listed in the program)
       57 + *      (the values of Lp1 to Lp7 are listed in the program)
  56   58   *      and
  57   59   *          |      2          14          |     -58.45
  58   60   *          | Lp1*s +...+Lp7*s    -  R(z) | <= 2
  59   61   *          |                             |
  60   62   *      Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2.
  61   63   *      In order to guarantee error in log below 1ulp, we compute log
  62   64   *      by
  63   65   *              log1p(f) = f - (hfsq - s*(hfsq+R)).
  64   66   *
  65   67   *      3. Finally, log1p(x) = k*ln2 + log1p(f).
↓ open down ↓ 19 lines elided ↑ open up ↑
  85   87   *
  86   88   * Note: Assuming log() return accurate answer, the following
  87   89   *       algorithm can be used to compute log1p(x) to within a few ULP:
  88   90   *
  89   91   *              u = 1+x;
  90   92   *              if (u == 1.0) return x ; else
  91   93   *                         return log(u)*(x/(u-1.0));
  92   94   *
  93   95   *       See HP-15C Advanced Functions Handbook, p.193.
  94   96   */
  95      -/* INDENT ON */
  96   97  
  97   98  #include "libm.h"
  98   99  
  99  100  static const double xxx[] = {
 100      -/* ln2_hi */    6.93147180369123816490e-01,     /* 3fe62e42 fee00000 */
 101      -/* ln2_lo */    1.90821492927058770002e-10,     /* 3dea39ef 35793c76 */
 102      -/* two54 */     1.80143985094819840000e+16,     /* 43500000 00000000 */
 103      -/* Lp1 */       6.666666666666735130e-01,       /* 3FE55555 55555593 */
 104      -/* Lp2 */       3.999999999940941908e-01,       /* 3FD99999 9997FA04 */
 105      -/* Lp3 */       2.857142874366239149e-01,       /* 3FD24924 94229359 */
 106      -/* Lp4 */       2.222219843214978396e-01,       /* 3FCC71C5 1D8E78AF */
 107      -/* Lp5 */       1.818357216161805012e-01,       /* 3FC74664 96CB03DE */
 108      -/* Lp6 */       1.531383769920937332e-01,       /* 3FC39A09 D078C69F */
 109      -/* Lp7 */       1.479819860511658591e-01,       /* 3FC2F112 DF3E5244 */
 110      -/* zero */      0.0
      101 +/* ln2_hi */
      102 +        6.93147180369123816490e-01,             /* 3fe62e42 fee00000 */
      103 +/* ln2_lo */ 1.90821492927058770002e-10,        /* 3dea39ef 35793c76 */
      104 +/* two54 */ 1.80143985094819840000e+16,         /* 43500000 00000000 */
      105 +/* Lp1 */ 6.666666666666735130e-01,             /* 3FE55555 55555593 */
      106 +/* Lp2 */ 3.999999999940941908e-01,             /* 3FD99999 9997FA04 */
      107 +/* Lp3 */ 2.857142874366239149e-01,             /* 3FD24924 94229359 */
      108 +/* Lp4 */ 2.222219843214978396e-01,             /* 3FCC71C5 1D8E78AF */
      109 +/* Lp5 */ 1.818357216161805012e-01,             /* 3FC74664 96CB03DE */
      110 +/* Lp6 */ 1.531383769920937332e-01,             /* 3FC39A09 D078C69F */
      111 +/* Lp7 */ 1.479819860511658591e-01,             /* 3FC2F112 DF3E5244 */
      112 +/* zero */ 0.0
 111  113  };
 112      -#define ln2_hi  xxx[0]
 113      -#define ln2_lo  xxx[1]
 114      -#define two54   xxx[2]
 115      -#define Lp1     xxx[3]
 116      -#define Lp2     xxx[4]
 117      -#define Lp3     xxx[5]
 118      -#define Lp4     xxx[6]
 119      -#define Lp5     xxx[7]
 120      -#define Lp6     xxx[8]
 121      -#define Lp7     xxx[9]
 122      -#define zero    xxx[10]
      114 +
      115 +#define ln2_hi          xxx[0]
      116 +#define ln2_lo          xxx[1]
      117 +#define two54           xxx[2]
      118 +#define Lp1             xxx[3]
      119 +#define Lp2             xxx[4]
      120 +#define Lp3             xxx[5]
      121 +#define Lp4             xxx[6]
      122 +#define Lp5             xxx[7]
      123 +#define Lp6             xxx[8]
      124 +#define Lp7             xxx[9]
      125 +#define zero            xxx[10]
 123  126  
 124  127  double
 125      -log1p(double x) {
 126      -        double  hfsq, f, c = 0.0, s, z, R, u;
 127      -        int     k, hx, hu, ax;
      128 +log1p(double x)
      129 +{
      130 +        double hfsq, f, c = 0.0, s, z, R, u;
      131 +        int k, hx, hu, ax;
 128  132  
 129      -        hx = ((int *)&x)[HIWORD];               /* high word of x */
      133 +        hx = ((int *)&x)[HIWORD]; /* high word of x */
 130  134          ax = hx & 0x7fffffff;
 131  135  
 132      -        if (ax >= 0x7ff00000) { /* x is inf or nan */
      136 +        if (ax >= 0x7ff00000) { /* x is inf or nan */
 133  137                  if (((hx - 0xfff00000) | ((int *)&x)[LOWORD]) == 0) /* -inf */
 134  138                          return (_SVID_libm_err(x, x, 44));
      139 +
 135  140                  return (x * x);
 136  141          }
 137  142  
 138  143          k = 1;
 139      -        if (hx < 0x3FDA827A) {  /* x < 0.41422  */
 140      -                if (ax >= 0x3ff00000)   /* x <= -1.0 */
      144 +
      145 +        if (hx < 0x3FDA827A) {                  /* x < 0.41422  */
      146 +                if (ax >= 0x3ff00000)           /* x <= -1.0 */
 141  147                          return (_SVID_libm_err(x, x, x == -1.0 ? 43 : 44));
 142      -                if (ax < 0x3e200000) {  /* |x| < 2**-29 */
      148 +
      149 +                if (ax < 0x3e200000) {          /* |x| < 2**-29 */
 143  150                          if (two54 + x > zero && /* raise inexact */
 144  151                              ax < 0x3c900000)    /* |x| < 2**-54 */
 145  152                                  return (x);
 146  153                          else
 147  154                                  return (x - x * x * 0.5);
 148  155                  }
      156 +
 149  157                  if (hx > 0 || hx <= (int)0xbfd2bec3) {  /* -0.2929<x<0.41422 */
 150  158                          k = 0;
 151  159                          f = x;
 152  160                          hu = 1;
 153  161                  }
 154  162          }
      163 +
 155  164          /* We will initialize 'c' here. */
 156  165          if (k != 0) {
 157  166                  if (hx < 0x43400000) {
 158  167                          u = 1.0 + x;
 159  168                          hu = ((int *)&u)[HIWORD];       /* high word of u */
 160  169                          k = (hu >> 20) - 1023;
      170 +
 161  171                          /*
 162  172                           * correction term
 163  173                           */
 164  174                          c = k > 0 ? 1.0 - (u - x) : x - (u - 1.0);
 165  175                          c /= u;
 166  176                  } else {
 167  177                          u = x;
 168  178                          hu = ((int *)&u)[HIWORD];       /* high word of u */
 169  179                          k = (hu >> 20) - 1023;
 170  180                          c = 0;
 171  181                  }
      182 +
 172  183                  hu &= 0x000fffff;
      184 +
 173  185                  if (hu < 0x6a09e) {     /* normalize u */
 174  186                          ((int *)&u)[HIWORD] = hu | 0x3ff00000;
 175      -                } else {                        /* normalize u/2 */
      187 +                } else {                /* normalize u/2 */
 176  188                          k += 1;
 177  189                          ((int *)&u)[HIWORD] = hu | 0x3fe00000;
 178  190                          hu = (0x00100000 - hu) >> 2;
 179  191                  }
      192 +
 180  193                  f = u - 1.0;
 181  194          }
      195 +
 182  196          hfsq = 0.5 * f * f;
 183      -        if (hu == 0) {          /* |f| < 2**-20 */
      197 +
      198 +        if (hu == 0) {                  /* |f| < 2**-20 */
 184  199                  if (f == zero) {
 185  200                          if (k == 0)
 186  201                                  return (zero);
      202 +
 187  203                          /* We already initialized 'c' before, when (k != 0) */
 188  204                          c += k * ln2_lo;
 189  205                          return (k * ln2_hi + c);
 190  206                  }
      207 +
 191  208                  R = hfsq * (1.0 - 0.66666666666666666 * f);
      209 +
 192  210                  if (k == 0)
 193  211                          return (f - R);
      212 +
 194  213                  return (k * ln2_hi - ((R - (k * ln2_lo + c)) - f));
 195  214          }
      215 +
 196  216          s = f / (2.0 + f);
 197  217          z = s * s;
 198      -        R = z * (Lp1 + z * (Lp2 + z * (Lp3 + z * (Lp4 + z * (Lp5 +
 199      -                z * (Lp6 + z * Lp7))))));
      218 +        R = z * (Lp1 + z * (Lp2 + z * (Lp3 + z * (Lp4 + z * (Lp5 + z * (Lp6 +
      219 +            z * Lp7))))));
      220 +
 200  221          if (k == 0)
 201  222                  return (f - (hfsq - s * (hfsq + R)));
 202      -        return (k * ln2_hi - ((hfsq - (s * (hfsq + R) +
 203      -                (k * ln2_lo + c))) - f));
      223 +
      224 +        return (k * ln2_hi -
      225 +            ((hfsq - (s * (hfsq + R) + (k * ln2_lo + c))) - f));
 204  226  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX