Print this page
    
5261 libm should stop using synonyms.h
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/lib/libm/common/LD/hypotl.c
          +++ new/usr/src/lib/libm/common/LD/hypotl.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  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
  
    | 
      ↓ open down ↓ | 
    19 lines elided | 
    
      ↑ open up ↑ | 
  
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  24   24   */
  25   25  /*
  26   26   * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  27   27   * Use is subject to license terms.
  28   28   */
  29   29  
  30      -#pragma weak hypotl = __hypotl
       30 +#pragma weak __hypotl = hypotl
  31   31  
  32   32  /*
  33   33   * hypotl(x,y)
  34   34   * Method :
  35   35   *      If z=x*x+y*y has error less than sqrt(2)/2 ulp than sqrt(z) has
  36   36   *      error less than 1 ulp.
  37   37   *      So, compute sqrt(x*x+y*y) with some care as follows:
  38   38   *      Assume x>y>0;
  39   39   *      1. save and set rounding to round-to-nearest
  40   40   *      2. if x > 2y  use
  41   41   *              x1*x1+(y*y+(x2*(x+x2))) for x*x+y*y
  42   42   *      where x1 = x with lower 32 bits cleared, x2 = x-x1; else
  43   43   *      3. if x <= 2y use
  44   44   *              t1*y1+((x-y)*(x-y)+(t1*y2+t2*y))
  45   45   *      where t1 = 2x with lower 64 bits cleared, t2 = 2x-t1, y1= y with
  46   46   *      lower 32 bits cleared, y2 = y-y1.
  47   47   *
  48   48   *      NOTE: DO NOT remove parenthsis!
  49   49   *
  50   50   * Special cases:
  51   51   *      hypot(x,y) is INF if x or y is +INF or -INF; else
  52   52   *      hypot(x,y) is NAN if x or y is NAN.
  53   53   *
  54   54   * Accuracy:
  55   55   *      hypot(x,y) returns sqrt(x^2+y^2) with error less than 1 ulps (units
  56   56   *      in the last place)
  57   57   */
  58   58  
  59   59  #include "libm.h"
  60   60  
  61   61  #if defined(__x86)
  62   62  extern enum fp_direction_type __swap87RD(enum fp_direction_type);
  63   63  
  64   64  #define k       0x7fff
  65   65  
  66   66  long double
  67   67  hypotl(long double x, long double y) {
  68   68          long double t1, t2, y1, y2, w;
  69   69          int *px = (int *) &x, *py = (int *) &y;
  70   70          int *pt1 = (int *) &t1, *py1 = (int *) &y1;
  71   71          enum fp_direction_type rd;
  72   72          int j, nx, ny, nz;
  73   73  
  74   74          px[2] &= 0x7fff;        /* clear sign bit and padding bits of x and y */
  75   75          py[2] &= 0x7fff;
  76   76          nx = px[2];             /* biased exponent of x and y */
  77   77          ny = py[2];
  78   78          if (ny > nx) {
  79   79                  w = x;
  80   80                  x = y;
  81   81                  y = w;
  82   82                  nz = ny;
  83   83                  ny = nx;
  84   84                  nx = nz;
  85   85          }                       /* force nx >= ny */
  86   86          if (nx - ny >= 66)
  87   87                  return (x + y); /* x / y >= 2**65 */
  88   88          if (nx < 0x5ff3 && ny > 0x205b) {       /* medium x,y */
  89   89                  /* save and set RD to Rounding to nearest */
  90   90                  rd = __swap87RD(fp_nearest);
  91   91                  w = x - y;
  92   92                  if (w > y) {
  93   93                          pt1[2] = px[2];
  94   94                          pt1[1] = px[1];
  95   95                          pt1[0] = 0;
  96   96                          t2 = x - t1;
  97   97                          x = sqrtl(t1 * t1 - (y * (-y) - t2 * (x + t1)));
  98   98                  } else {
  99   99                          x += x;
 100  100                          py1[2] = py[2];
 101  101                          py1[1] = py[1];
 102  102                          py1[0] = 0;
 103  103                          y2 = y - y1;
 104  104                          pt1[2] = px[2];
 105  105                          pt1[1] = px[1];
 106  106                          pt1[0] = 0;
 107  107                          t2 = x - t1;
 108  108                          x = sqrtl(t1 * y1 - (w * (-w) - (t2 * y1 + y2 * x)));
 109  109                  }
 110  110                  if (rd != fp_nearest)
 111  111                          __swap87RD(rd); /* restore rounding mode */
 112  112                  return (x);
 113  113          } else {
 114  114                  if (nx == k || ny == k) {       /* x or y is INF or NaN */
 115  115                          /* since nx >= ny; nx is always k within this block */
 116  116                          if (px[1] == 0x80000000 && px[0] == 0)
 117  117                                  return (x);
 118  118                          else if (ny == k && py[1] == 0x80000000 && py[0] == 0)
 119  119                                  return (y);
 120  120                          else
 121  121                                  return (x + y);
 122  122                  }
 123  123                  if (ny == 0) {
 124  124                          if (y == 0.L || x == 0.L)
 125  125                                  return (x + y);
 126  126                          pt1[2] = 0x3fff + 16381;
 127  127                          pt1[1] = 0x80000000;
 128  128                          pt1[0] = 0;
 129  129                          py1[2] = 0x3fff - 16381;
 130  130                          py1[1] = 0x80000000;
 131  131                          py1[0] = 0;
 132  132                          x *= t1;
 133  133                          y *= t1;
 134  134                          return (y1 * hypotl(x, y));
 135  135                  }
 136  136                  j = nx - 0x3fff;
 137  137                  px[2] -= j;
 138  138                  py[2] -= j;
 139  139                  pt1[2] = nx;
 140  140                  pt1[1] = 0x80000000;
 141  141                  pt1[0] = 0;
 142  142                  return (t1 * hypotl(x, y));
 143  143          }
 144  144  }
 145  145  #endif
  
    | 
      ↓ open down ↓ | 
    105 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX