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

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libm/common/complex/cacos.c
          +++ new/usr/src/lib/libm/common/complex/cacos.c
↓ open down ↓ 14 lines elided ↑ open up ↑
  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   23   * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  24   24   */
       25 +
  25   26  /*
  26   27   * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  27   28   * Use is subject to license terms.
  28   29   */
  29   30  
  30   31  #pragma weak __cacos = cacos
  31   32  
  32      -/* INDENT OFF */
       33 +
  33   34  /*
  34   35   * dcomplex cacos(dcomplex z);
  35   36   *
  36   37   * Alogrithm
  37   38   * (based on T.E.Hull, Thomas F. Fairgrieve and Ping Tak Peter Tang's
  38   39   * paper "Implementing the Complex Arcsine and Arccosine Functins Using
  39   40   * Exception Handling", ACM TOMS, Vol 23, pp 299-335)
  40   41   *
  41   42   * The principal value of complex inverse cosine function cacos(z),
  42   43   * where z = x+iy, can be defined by
  43   44   *
  44      - *      cacos(z) = acos(B) - i sign(y) log (A + sqrt(A*A-1)),
       45 + *      cacos(z) = acos(B) - i sign(y) log (A + sqrt(A*A-1)),
  45   46   *
  46   47   * where the log function is the natural log, and
  47   48   *             ____________           ____________
  48   49   *       1    /     2    2      1    /     2    2
  49   50   *  A = ---  / (x+1)  + y   +  ---  / (x-1)  + y
  50   51   *       2 \/                   2 \/
  51   52   *             ____________           ____________
  52   53   *       1    /     2    2      1    /     2    2
  53   54   *  B = ---  / (x+1)  + y   -  ---  / (x-1)  + y   .
  54   55   *       2 \/                   2 \/
↓ open down ↓ 90 lines elided ↑ open up ↑
 145  146   *              cacos(x+i*y)~ [ 0 - i 0,                              if x = 1,
 146  147   *                            [
 147  148   *                            [ y/sqrt(x*x-1) - i log(x+sqrt(x*x-1)), if x > 1.
 148  149   *
 149  150   *      Note: y/sqrt(x*x-1) ~ y/x when x >= 2**26.
 150  151   *  case 3. y < 4 sqrt(u), where u = minimum normal x.
 151  152   *      After case 1 and 2, this will only occurs when x=1. When x=1, we have
 152  153   *         A = (sqrt(4+y*y)+y)/2 ~ 1 + y/2 + y^2/8 + ...
 153  154   *      and
 154  155   *         B = 1/A = 1 - y/2 + y^2/8 + ...
 155      - *      Since
      156 + *      Since
 156  157   *         cos(sqrt(y)) ~ 1 - y/2 + ...
 157  158   *      we have, for the real part,
 158  159   *         acos(B) ~ acos(1 - y/2) ~ sqrt(y)
 159  160   *      For the imaginary part,
 160  161   *         log(A+sqrt(A*A-1)) ~ log(1+y/2+sqrt(2*y/2))
 161  162   *                            = log(1+y/2+sqrt(y))
 162  163   *                            = (y/2+sqrt(y)) - (y/2+sqrt(y))^2/2 + ...
 163  164   *                            ~ sqrt(y) - y*(sqrt(y)+y/2)/2
 164  165   *                            ~ sqrt(y)
 165  166   *
 166  167   *  case 4. y >= (x+1)/ulp(0.5). In this case, A ~ y and B ~ x/y. Thus
 167  168   *         real part = acos(B) ~ pi/2
 168      - *      and
      169 + *      and
 169  170   *         imag part = log(y+sqrt(y*y-one))
 170  171   *
 171  172   *  case 5. Both x and y are large: x and y > sqrt(M)/8, where M = maximum x
 172  173   *      In this case,
 173  174   *         A ~ sqrt(x*x+y*y)
 174  175   *         B ~ x/sqrt(x*x+y*y).
 175  176   *      Thus
 176  177   *         real part = acos(B) = atan(y/x),
 177  178   *         imag part = log(A+sqrt(A*A-1)) ~ log(2A)
 178  179   *                   = log(2) + 0.5*log(x*x+y*y)
↓ open down ↓ 2 lines elided ↑ open up ↑
 181  182   *  case 6. x < 4 sqrt(u). In this case, we have
 182  183   *          A ~ sqrt(1+y*y), B = x/sqrt(1+y*y).
 183  184   *      Since B is tiny, we have
 184  185   *          real part = acos(B) ~ pi/2
 185  186   *          imag part = log(A+sqrt(A*A-1)) = log (A+sqrt(y*y))
 186  187   *                    = log(y+sqrt(1+y*y))
 187  188   *                    = 0.5*log(y^2+2ysqrt(1+y^2)+1+y^2)
 188  189   *                    = 0.5*log(1+2y(y+sqrt(1+y^2)));
 189  190   *                    = 0.5*log1p(2y(y+A));
 190  191   *
 191      - *      cacos(z) = acos(B) - i sign(y) log (A + sqrt(A*A-1)),
      192 + *      cacos(z) = acos(B) - i sign(y) log (A + sqrt(A*A-1)),
 192  193   */
 193      -/* INDENT ON */
 194  194  
 195  195  #include "libm.h"
 196  196  #include "complex_wrapper.h"
 197  197  
 198      -/* INDENT OFF */
 199      -static const double
 200      -        zero = 0.0,
      198 +static const double zero = 0.0,
 201  199          one = 1.0,
 202      -        E = 1.11022302462515654042e-16,                 /* 2**-53 */
      200 +        E = 1.11022302462515654042e-16, /* 2**-53 */
 203  201          ln2 = 6.93147180559945286227e-01,
 204  202          pi = 3.1415926535897931159979634685,
 205  203          pi_l = 1.224646799147353177e-16,
 206  204          pi_2 = 1.570796326794896558e+00,
 207  205          pi_2_l = 6.123233995736765886e-17,
 208  206          pi_4 = 0.78539816339744827899949,
 209  207          pi_4_l = 3.061616997868382943e-17,
 210  208          pi3_4 = 2.356194490192344836998,
 211  209          pi3_4_l = 9.184850993605148829195e-17,
 212  210          Foursqrtu = 5.96667258496016539463e-154,        /* 2**(-509) */
 213  211          Acrossover = 1.5,
 214  212          Bcrossover = 0.6417,
 215  213          half = 0.5;
 216      -/* INDENT ON */
      214 +
 217  215  
 218  216  dcomplex
 219      -cacos(dcomplex z) {
      217 +cacos(dcomplex z)
      218 +{
 220  219          double x, y, t, R, S, A, Am1, B, y2, xm1, xp1, Apx;
 221  220          int ix, iy, hx, hy;
 222  221          unsigned lx, ly;
 223  222          dcomplex ans;
 224  223  
 225  224          x = D_RE(z);
 226  225          y = D_IM(z);
 227  226          hx = HI_WORD(x);
 228  227          lx = LO_WORD(x);
 229  228          hy = HI_WORD(y);
↓ open down ↓ 7 lines elided ↑ open up ↑
 237  236                          D_RE(ans) = pi_2;
 238  237                          D_IM(ans) = -y;
 239  238                          return (ans);
 240  239                  }
 241  240          }
 242  241  
 243  242          /* |y| is inf or NaN */
 244  243          if (iy >= 0x7ff00000) {
 245  244                  if (ISINF(iy, ly)) {    /* cacos(x + i inf) = pi/2  - i inf */
 246  245                          D_IM(ans) = -y;
      246 +
 247  247                          if (ix < 0x7ff00000) {
 248  248                                  D_RE(ans) = pi_2 + pi_2_l;
 249  249                          } else if (ISINF(ix, lx)) {
 250  250                                  if (hx >= 0)
 251  251                                          D_RE(ans) = pi_4 + pi_4_l;
 252  252                                  else
 253  253                                          D_RE(ans) = pi3_4 + pi3_4_l;
 254  254                          } else {
 255  255                                  D_RE(ans) = x;
 256  256                          }
 257  257                  } else {                /* cacos(x + i NaN) = NaN  + i NaN */
 258  258                          D_RE(ans) = y + x;
      259 +
 259  260                          if (ISINF(ix, lx))
 260  261                                  D_IM(ans) = -fabs(x);
 261  262                          else
 262  263                                  D_IM(ans) = y;
 263  264                  }
      265 +
 264  266                  return (ans);
 265  267          }
 266  268  
 267  269          x = fabs(x);
 268  270          y = fabs(y);
 269  271  
 270  272          /* x is inf or NaN */
 271      -        if (ix >= 0x7ff00000) { /* x is inf or NaN */
      273 +        if (ix >= 0x7ff00000) {         /* x is inf or NaN */
 272  274                  if (ISINF(ix, lx)) {    /* x is INF */
 273  275                          D_IM(ans) = -x;
      276 +
 274  277                          if (iy >= 0x7ff00000) {
 275  278                                  if (ISINF(iy, ly)) {
 276      -                                        /* INDENT OFF */
 277      -                                        /* cacos(inf + i inf) = pi/4 - i inf */
 278      -                                        /* cacos(-inf+ i inf) =3pi/4 - i inf */
 279      -                                        /* INDENT ON */
      279 +                                        /*
      280 +                                         * cacos(inf + i inf) = pi/4 - i inf
      281 +                                         * cacos(-inf+ i inf) =3pi/4 - i inf
      282 +                                         */
 280  283                                          if (hx >= 0)
 281  284                                                  D_RE(ans) = pi_4 + pi_4_l;
 282  285                                          else
 283  286                                                  D_RE(ans) = pi3_4 + pi3_4_l;
 284      -                                } else
 285      -                                        /* INDENT OFF */
 286      -                                        /* cacos(inf + i NaN) = NaN  - i inf  */
 287      -                                        /* INDENT ON */
      287 +                                } else {
      288 +                                        /*
      289 +                                         * cacos(inf + i NaN) = NaN  - i inf
      290 +                                         */
 288  291                                          D_RE(ans) = y + y;
      292 +                                }
 289  293                          } else
 290      -                                /* INDENT OFF */
 291      -                                /* cacos(inf + iy ) = 0  - i inf */
 292      -                                /* cacos(-inf+ iy  ) = pi - i inf */
 293      -                                /* INDENT ON */
 294      -                        if (hx >= 0)
      294 +                        /*
      295 +                         * cacos(inf + iy ) = 0  - i inf
      296 +                         * cacos(-inf+ iy  ) = pi - i inf
      297 +                         */
      298 +                        if (hx >= 0) {
 295  299                                  D_RE(ans) = zero;
 296      -                        else
      300 +                        } else {
 297  301                                  D_RE(ans) = pi + pi_l;
      302 +                        }
 298  303                  } else {                /* x is NaN */
 299      -                        /* INDENT OFF */
      304 +
 300  305                          /*
 301  306                           * cacos(NaN + i inf) = NaN  - i inf
 302  307                           * cacos(NaN + i y  ) = NaN  + i NaN
 303  308                           * cacos(NaN + i NaN) = NaN  + i NaN
 304  309                           */
 305      -                        /* INDENT ON */
 306  310                          D_RE(ans) = x + y;
 307      -                        if (iy >= 0x7ff00000) {
      311 +
      312 +                        if (iy >= 0x7ff00000)
 308  313                                  D_IM(ans) = -y;
 309      -                        } else {
      314 +                        else
 310  315                                  D_IM(ans) = x;
 311      -                        }
 312  316                  }
      317 +
 313  318                  if (hy < 0)
 314  319                          D_IM(ans) = -D_IM(ans);
      320 +
 315  321                  return (ans);
 316  322          }
 317  323  
 318      -        if ((iy | ly) == 0) {   /* region 1: y=0 */
      324 +        if ((iy | ly) == 0) {           /* region 1: y=0 */
 319  325                  if (ix < 0x3ff00000) {  /* |x| < 1 */
 320  326                          D_RE(ans) = acos(x);
 321  327                          D_IM(ans) = zero;
 322  328                  } else {
 323  329                          D_RE(ans) = zero;
 324      -                        if (ix >= 0x43500000)   /* |x| >= 2**54 */
      330 +
      331 +                        if (ix >= 0x43500000) {         /* |x| >= 2**54 */
 325  332                                  D_IM(ans) = ln2 + log(x);
 326      -                        else if (ix >= 0x3ff80000)      /* x > Acrossover */
      333 +                        } else if (ix >= 0x3ff80000) {  /* x > Acrossover */
 327  334                                  D_IM(ans) = log(x + sqrt((x - one) * (x +
 328      -                                        one)));
 329      -                        else {
      335 +                                    one)));
      336 +                        } else {
 330  337                                  xm1 = x - one;
 331  338                                  D_IM(ans) = log1p(xm1 + sqrt(xm1 * (x + one)));
 332  339                          }
 333  340                  }
 334  341          } else if (y <= E * fabs(x - one)) {    /* region 2: y < tiny*|x-1| */
 335      -                if (ix < 0x3ff00000) {  /* x < 1 */
      342 +                if (ix < 0x3ff00000) {          /* x < 1 */
 336  343                          D_RE(ans) = acos(x);
 337  344                          D_IM(ans) = y / sqrt((one + x) * (one - x));
 338  345                  } else if (ix >= 0x43500000) {  /* |x| >= 2**54 */
 339  346                          D_RE(ans) = y / x;
 340  347                          D_IM(ans) = ln2 + log(x);
 341  348                  } else {
 342  349                          t = sqrt((x - one) * (x + one));
 343  350                          D_RE(ans) = y / t;
      351 +
 344  352                          if (ix >= 0x3ff80000)   /* x > Acrossover */
 345  353                                  D_IM(ans) = log(x + t);
 346  354                          else
 347  355                                  D_IM(ans) = log1p((x - one) + t);
 348  356                  }
 349  357          } else if (y < Foursqrtu) {     /* region 3 */
 350  358                  t = sqrt(y);
 351  359                  D_RE(ans) = t;
 352  360                  D_IM(ans) = t;
 353      -        } else if (E * y - one >= x) {  /* region 4 */
      361 +        } else if (E * y - one >= x) {                          /* region 4 */
 354  362                  D_RE(ans) = pi_2;
 355  363                  D_IM(ans) = ln2 + log(y);
 356  364          } else if (ix >= 0x5fc00000 || iy >= 0x5fc00000) {      /* x,y>2**509 */
 357  365                  /* region 5: x+1 or y is very large (>= sqrt(max)/8) */
 358  366                  t = x / y;
 359  367                  D_RE(ans) = atan(y / x);
 360  368                  D_IM(ans) = ln2 + log(y) + half * log1p(t * t);
 361  369          } else if (x < Foursqrtu) {
 362  370                  /* region 6: x is very small, < 4sqrt(min) */
 363  371                  D_RE(ans) = pi_2;
 364  372                  A = sqrt(one + y * y);
      373 +
 365  374                  if (iy >= 0x3ff80000)   /* if y > Acrossover */
 366  375                          D_IM(ans) = log(y + A);
 367  376                  else
 368  377                          D_IM(ans) = half * log1p((y + y) * (y + A));
 369      -        } else {        /* safe region */
      378 +        } else {                        /* safe region */
 370  379                  y2 = y * y;
 371  380                  xp1 = x + one;
 372  381                  xm1 = x - one;
 373  382                  R = sqrt(xp1 * xp1 + y2);
 374  383                  S = sqrt(xm1 * xm1 + y2);
 375  384                  A = half * (R + S);
 376  385                  B = x / A;
 377      -                if (B <= Bcrossover)
      386 +
      387 +                if (B <= Bcrossover) {
 378  388                          D_RE(ans) = acos(B);
 379      -                else {          /* use atan and an accurate approx to a-x */
      389 +                } else {        /* use atan and an accurate approx to a-x */
 380  390                          Apx = A + x;
      391 +
 381  392                          if (x <= one)
 382  393                                  D_RE(ans) = atan(sqrt(half * Apx * (y2 / (R +
 383      -                                        xp1) + (S - xm1))) / x);
      394 +                                    xp1) + (S - xm1))) / x);
 384  395                          else
 385  396                                  D_RE(ans) = atan((y * sqrt(half * (Apx / (R +
 386      -                                        xp1) + Apx / (S + xm1)))) / x);
      397 +                                    xp1) + Apx / (S + xm1)))) / x);
 387  398                  }
      399 +
 388  400                  if (A <= Acrossover) {
 389  401                          /* use log1p and an accurate approx to A-1 */
 390  402                          if (x < one)
 391  403                                  Am1 = half * (y2 / (R + xp1) + y2 / (S - xm1));
 392  404                          else
 393  405                                  Am1 = half * (y2 / (R + xp1) + (S + xm1));
      406 +
 394  407                          D_IM(ans) = log1p(Am1 + sqrt(Am1 * (A + one)));
 395  408                  } else {
 396  409                          D_IM(ans) = log(A + sqrt(A * A - one));
 397  410                  }
 398  411          }
      412 +
 399  413          if (hx < 0)
 400  414                  D_RE(ans) = pi - D_RE(ans);
      415 +
 401  416          if (hy >= 0)
 402  417                  D_IM(ans) = -D_IM(ans);
      418 +
 403  419          return (ans);
 404  420  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX