1 /*
   2  * Copyright (c) 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 // This file is available under and governed by the GNU General Public
  27 // License version 2 only, as published by the Free Software Foundation.
  28 // However, the following notice accompanied the original version of this
  29 // file:
  30 //
  31 // Copyright 2010 the V8 project authors. All rights reserved.
  32 // Redistribution and use in source and binary forms, with or without
  33 // modification, are permitted provided that the following conditions are
  34 // met:
  35 //
  36 //     * Redistributions of source code must retain the above copyright
  37 //       notice, this list of conditions and the following disclaimer.
  38 //     * Redistributions in binary form must reproduce the above
  39 //       copyright notice, this list of conditions and the following
  40 //       disclaimer in the documentation and/or other materials provided
  41 //       with the distribution.
  42 //     * Neither the name of Google Inc. nor the names of its
  43 //       contributors may be used to endorse or promote products derived
  44 //       from this software without specific prior written permission.
  45 //
  46 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  47 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  48 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  49 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  50 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  51 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  52 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  53 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  54 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  55 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  56 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  57 
  58 package jdk.nashorn.internal.runtime.doubleconv;
  59 
  60 // Helper functions for doubles.
  61 class IeeeDouble {
  62 
  63     // We assume that doubles and long have the same endianness.
  64     static long doubleToLong(final double d)   { return Double.doubleToRawLongBits(d); }
  65     static double longToDouble(final long d64) { return Double.longBitsToDouble(d64); }
  66 
  67     static final long kSignMask = 0x8000000000000000L;
  68     static final long kExponentMask = 0x7FF0000000000000L;
  69     static final long kSignificandMask = 0x000FFFFFFFFFFFFFL;
  70     static final long kHiddenBit = 0x0010000000000000L;
  71     static final int kPhysicalSignificandSize = 52;  // Excludes the hidden bit.
  72     static final int kSignificandSize = 53;
  73 
  74     static private final int kExponentBias = 0x3FF + kPhysicalSignificandSize;
  75     static private final int kDenormalExponent = -kExponentBias + 1;
  76     static private final int kMaxExponent = 0x7FF - kExponentBias;
  77     static private final long kInfinity = 0x7FF0000000000000L;
  78     static private final long kNaN = 0x7FF8000000000000L;
  79 
  80     static DiyFp asDiyFp(final long d64) {
  81         assert (!isSpecial(d64));
  82         return new DiyFp(significand(d64), exponent(d64));
  83     }
  84 
  85     // The value encoded by this Double must be strictly greater than 0.
  86     static DiyFp asNormalizedDiyFp(final long d64) {
  87         assert (value(d64) > 0.0);
  88         long f = significand(d64);
  89         int e = exponent(d64);
  90 
  91         // The current double could be a denormal.
  92         while ((f & kHiddenBit) == 0) {
  93             f <<= 1;
  94             e--;
  95         }
  96         // Do the final shifts in one go.
  97         f <<= DiyFp.kSignificandSize - kSignificandSize;
  98         e -= DiyFp.kSignificandSize - kSignificandSize;
  99 
 100         return new DiyFp(f, e);
 101     }
 102 
 103     // Returns the next greater double. Returns +infinity on input +infinity.
 104     static double nextDouble(final long d64) {
 105         if (d64 == kInfinity) return longToDouble(kInfinity);
 106         if (sign(d64) < 0 && significand(d64) == 0) {
 107             // -0.0
 108             return 0.0;
 109         }
 110         if (sign(d64) < 0) {
 111             return longToDouble(d64 - 1);
 112         } else {
 113             return longToDouble(d64 + 1);
 114         }
 115     }
 116 
 117     static double previousDouble(final long d64) {
 118         if (d64 == (kInfinity | kSignMask)) return -Infinity();
 119         if (sign(d64) < 0) {
 120             return longToDouble(d64 + 1);
 121         } else {
 122             if (significand(d64) == 0) return -0.0;
 123             return longToDouble(d64 - 1);
 124         }
 125     }
 126 
 127     static int exponent(final long d64) {
 128         if (isDenormal(d64)) return kDenormalExponent;
 129 
 130         final int biased_e = (int) ((d64 & kExponentMask) >>> kPhysicalSignificandSize);
 131         return biased_e - kExponentBias;
 132     }
 133 
 134     static long significand(final long d64) {
 135         final long significand = d64 & kSignificandMask;
 136         if (!isDenormal(d64)) {
 137             return significand + kHiddenBit;
 138         } else {
 139             return significand;
 140         }
 141     }
 142 
 143     // Returns true if the double is a denormal.
 144     static boolean isDenormal(final long d64) {
 145         return (d64 & kExponentMask) == 0L;
 146     }
 147 
 148     // We consider denormals not to be special.
 149     // Hence only Infinity and NaN are special.
 150     static boolean isSpecial(final long d64) {
 151         return (d64 & kExponentMask) == kExponentMask;
 152     }
 153 
 154     static boolean isNaN(final long d64) {
 155         return ((d64 & kExponentMask) == kExponentMask) &&
 156                 ((d64 & kSignificandMask) != 0L);
 157     }
 158 
 159 
 160     static boolean isInfinite(final long d64) {
 161         return ((d64 & kExponentMask) == kExponentMask) &&
 162                 ((d64 & kSignificandMask) == 0L);
 163     }
 164 
 165 
 166     static int sign(final long d64) {
 167         return (d64 & kSignMask) == 0L ? 1 : -1;
 168     }
 169 
 170 
 171     // Computes the two boundaries of this.
 172     // The bigger boundary (m_plus) is normalized. The lower boundary has the same
 173     // exponent as m_plus.
 174     // Precondition: the value encoded by this Double must be greater than 0.
 175     static void normalizedBoundaries(final long d64, final DiyFp m_minus, final DiyFp m_plus) {
 176         assert (value(d64) > 0.0);
 177         final DiyFp v = asDiyFp(d64);
 178         m_plus.setF((v.f() << 1) + 1);
 179         m_plus.setE(v.e() - 1);
 180         m_plus.normalize();
 181         if (lowerBoundaryIsCloser(d64)) {
 182             m_minus.setF((v.f() << 2) - 1);
 183             m_minus.setE(v.e() - 2);
 184         } else {
 185             m_minus.setF((v.f() << 1) - 1);
 186             m_minus.setE(v.e() - 1);
 187         }
 188         m_minus.setF(m_minus.f() << (m_minus.e() - m_plus.e()));
 189         m_minus.setE(m_plus.e());
 190     }
 191 
 192     static boolean lowerBoundaryIsCloser(final long d64) {
 193         // The boundary is closer if the significand is of the form f == 2^p-1 then
 194         // the lower boundary is closer.
 195         // Think of v = 1000e10 and v- = 9999e9.
 196         // Then the boundary (== (v - v-)/2) is not just at a distance of 1e9 but
 197         // at a distance of 1e8.
 198         // The only exception is for the smallest normal: the largest denormal is
 199         // at the same distance as its successor.
 200         // Note: denormals have the same exponent as the smallest normals.
 201         final boolean physical_significand_is_zero = ((d64 & kSignificandMask) == 0);
 202         return physical_significand_is_zero && (exponent(d64) != kDenormalExponent);
 203     }
 204 
 205     static double value(final long d64) {
 206         return longToDouble(d64);
 207     }
 208 
 209     // Returns the significand size for a given order of magnitude.
 210     // If v = f*2^e with 2^p-1 <= f <= 2^p then p+e is v's order of magnitude.
 211     // This function returns the number of significant binary digits v will have
 212     // once it's encoded into a double. In almost all cases this is equal to
 213     // kSignificandSize. The only exceptions are denormals. They start with
 214     // leading zeroes and their effective significand-size is hence smaller.
 215     static int significandSizeForOrderOfMagnitude(final int order) {
 216         if (order >= (kDenormalExponent + kSignificandSize)) {
 217             return kSignificandSize;
 218         }
 219         if (order <= kDenormalExponent) return 0;
 220         return order - kDenormalExponent;
 221     }
 222 
 223     static double Infinity() {
 224         return longToDouble(kInfinity);
 225     }
 226 
 227     static double NaN() {
 228         return longToDouble(kNaN);
 229     }
 230 
 231 }
 232 
 233