1 /*
   2  * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 /**
  27  * A transliteration of the "Freely Distributable Math Library"
  28  * algorithms from C into Java. That is, this port of the algorithms
  29  * is as close to the C originals as possible while still being
  30  * readable legal Java.
  31  */
  32 public class FdlibmTranslit {
  33     private FdlibmTranslit() {
  34         throw new UnsupportedOperationException("No FdLibmTranslit instances for you.");
  35     }
  36 
  37     /**
  38      * Return the low-order 32 bits of the double argument as an int.
  39      */
  40     private static int __LO(double x) {
  41         long transducer = Double.doubleToRawLongBits(x);
  42         return (int)transducer;
  43     }
  44 
  45     /**
  46      * Return a double with its low-order bits of the second argument
  47      * and the high-order bits of the first argument..
  48      */
  49     private static double __LO(double x, int low) {
  50         long transX = Double.doubleToRawLongBits(x);
  51         return Double.longBitsToDouble((transX & 0xFFFF_FFFF_0000_0000L)|low );
  52     }
  53 
  54     /**
  55      * Return the high-order 32 bits of the double argument as an int.
  56      */
  57     private static int __HI(double x) {
  58         long transducer = Double.doubleToRawLongBits(x);
  59         return (int)(transducer >> 32);
  60     }
  61 
  62     /**
  63      * Return a double with its high-order bits of the second argument
  64      * and the low-order bits of the first argument..
  65      */
  66     private static double __HI(double x, int high) {
  67         long transX = Double.doubleToRawLongBits(x);
  68         return Double.longBitsToDouble((transX & 0x0000_0000_FFFF_FFFFL)|( ((long)high)) << 32 );
  69     }
  70 
  71     public static double hypot(double x, double y) {
  72         return Hypot.compute(x, y);
  73     }
  74 
  75     /**
  76      * cbrt(x)
  77      * Return cube root of x
  78      */
  79     public static class Cbrt {
  80         // unsigned
  81         private static final int B1 = 715094163; /* B1 = (682-0.03306235651)*2**20 */
  82         private static final int B2 = 696219795; /* B2 = (664-0.03306235651)*2**20 */
  83 
  84         private static final double C =  5.42857142857142815906e-01; /* 19/35     = 0x3FE15F15, 0xF15F15F1 */
  85         private static final double D = -7.05306122448979611050e-01; /* -864/1225 = 0xBFE691DE, 0x2532C834 */
  86         private static final double E =  1.41428571428571436819e+00; /* 99/70     = 0x3FF6A0EA, 0x0EA0EA0F */
  87         private static final double F =  1.60714285714285720630e+00; /* 45/28     = 0x3FF9B6DB, 0x6DB6DB6E */
  88         private static final double G =  3.57142857142857150787e-01; /* 5/14      = 0x3FD6DB6D, 0xB6DB6DB7 */
  89 
  90         public static strictfp double compute(double x) {
  91             int     hx;
  92             double  r, s, t=0.0, w;
  93             int sign; // unsigned
  94 
  95             hx = __HI(x);           // high word of x
  96             sign = hx & 0x80000000;             // sign= sign(x)
  97             hx  ^= sign;
  98             if (hx >= 0x7ff00000)
  99                 return (x+x); // cbrt(NaN,INF) is itself
 100             if ((hx | __LO(x)) == 0)
 101                 return(x);          // cbrt(0) is itself
 102 
 103             x = __HI(x, hx);   // x <- |x|
 104             // rough cbrt to 5 bits
 105             if (hx < 0x00100000) {               // subnormal number
 106                 t = __HI(t, 0x43500000);          // set t= 2**54
 107                 t *= x;
 108                 t = __HI(t, __HI(t)/3+B2);
 109             } else {
 110                 t = __HI(t, hx/3+B1);
 111             }
 112 
 113             // new cbrt to 23 bits, may be implemented in single precision
 114             r = t * t/x;
 115             s = C + r*t;
 116             t *= G + F/(s + E + D/s);
 117 
 118             // chopped to 20 bits and make it larger than cbrt(x)
 119             t = __LO(t, 0);
 120             t = __HI(t, __HI(t)+0x00000001);
 121 
 122 
 123             // one step newton iteration to 53 bits with error less than 0.667 ulps
 124             s = t * t;          // t*t is exact
 125             r = x / s;
 126             w = t + t;
 127             r= (r - t)/(w + r);  // r-s is exact
 128             t= t + t*r;
 129 
 130             // retore the sign bit
 131             t = __HI(t, __HI(t) | sign);
 132             return(t);
 133         }
 134     }
 135 
 136     /**
 137      * hypot(x,y)
 138      *
 139      * Method :
 140      *      If (assume round-to-nearest) z = x*x + y*y
 141      *      has error less than sqrt(2)/2 ulp, than
 142      *      sqrt(z) has error less than 1 ulp (exercise).
 143      *
 144      *      So, compute sqrt(x*x + y*y) with some care as
 145      *      follows to get the error below 1 ulp:
 146      *
 147      *      Assume x > y > 0;
 148      *      (if possible, set rounding to round-to-nearest)
 149      *      1. if x > 2y  use
 150      *              x1*x1 + (y*y + (x2*(x + x1))) for x*x + y*y
 151      *      where x1 = x with lower 32 bits cleared, x2 = x - x1; else
 152      *      2. if x <= 2y use
 153      *              t1*y1 + ((x-y) * (x-y) + (t1*y2 + t2*y))
 154      *      where t1 = 2x with lower 32 bits cleared, t2 = 2x - t1,
 155      *      y1= y with lower 32 bits chopped, y2 = y - y1.
 156      *
 157      *      NOTE: scaling may be necessary if some argument is too
 158      *            large or too tiny
 159      *
 160      * Special cases:
 161      *      hypot(x,y) is INF if x or y is +INF or -INF; else
 162      *      hypot(x,y) is NAN if x or y is NAN.
 163      *
 164      * Accuracy:
 165      *      hypot(x,y) returns sqrt(x^2 + y^2) with error less
 166      *      than 1 ulps (units in the last place)
 167      */
 168     static class Hypot {
 169         public static double compute(double x, double y) {
 170             double a = x;
 171             double b = y;
 172             double t1, t2, y1, y2, w;
 173             int j, k, ha, hb;
 174 
 175             ha = __HI(x) & 0x7fffffff;        // high word of  x
 176             hb = __HI(y) & 0x7fffffff;        // high word of  y
 177             if(hb > ha) {
 178                 a = y;
 179                 b = x;
 180                 j = ha;
 181                 ha = hb;
 182                 hb = j;
 183             } else {
 184                 a = x;
 185                 b = y;
 186             }
 187             a = __HI(a, ha);   // a <- |a|
 188             b = __HI(b, hb);   // b <- |b|
 189             if ((ha - hb) > 0x3c00000) {
 190                 return a + b;  // x / y > 2**60
 191             }
 192             k=0;
 193             if (ha > 0x5f300000) {   // a>2**500
 194                 if (ha >= 0x7ff00000) {       // Inf or NaN
 195                     w = a + b;                // for sNaN
 196                     if (((ha & 0xfffff) | __LO(a)) == 0)
 197                         w = a;
 198                     if (((hb ^ 0x7ff00000) | __LO(b)) == 0)
 199                         w = b;
 200                     return w;
 201                 }
 202                 // scale a and b by 2**-600
 203                 ha -= 0x25800000;
 204                 hb -= 0x25800000;
 205                 k += 600;
 206                 a = __HI(a, ha);
 207                 b = __HI(b, hb);
 208             }
 209             if (hb < 0x20b00000) {   // b < 2**-500
 210                 if (hb <= 0x000fffff) {      // subnormal b or 0 */
 211                     if ((hb | (__LO(b))) == 0)
 212                         return a;
 213                     t1 = 0;
 214                     t1 = __HI(t1, 0x7fd00000);  // t1=2^1022
 215                     b *= t1;
 216                     a *= t1;
 217                     k -= 1022;
 218                 } else {            // scale a and b by 2^600
 219                     ha += 0x25800000;       // a *= 2^600
 220                     hb += 0x25800000;       // b *= 2^600
 221                     k -= 600;
 222                     a = __HI(a, ha);
 223                     b = __HI(b, hb);
 224                 }
 225             }
 226             // medium size a and b
 227             w = a - b;
 228             if (w > b) {
 229                 t1 = 0;
 230                 t1 = __HI(t1, ha);
 231                 t2 = a - t1;
 232                 w  = Math.sqrt(t1*t1 - (b*(-b) - t2 * (a + t1)));
 233             } else {
 234                 a  = a + a;
 235                 y1 = 0;
 236                 y1 = __HI(y1, hb);
 237                 y2 = b - y1;
 238                 t1 = 0;
 239                 t1 = __HI(t1, ha + 0x00100000);
 240                 t2 = a - t1;
 241                 w  = Math.sqrt(t1*y1 - (w*(-w) - (t1*y2 + t2*b)));
 242             }
 243             if (k != 0) {
 244                 t1 = 1.0;
 245                 int t1_hi = __HI(t1);
 246                 t1_hi += (k << 20);
 247                 t1 = __HI(t1, t1_hi);
 248                 return t1 * w;
 249             } else
 250                 return w;
 251         }
 252     }
 253 }