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 public class CachedPowers {
  61 
  62     static class CachedPower {
  63         final private long significand;
  64         final private int binaryExponent;
  65         final private int decimalExponent;
  66 
  67         CachedPower(final long significand, final int binaryExponent, final int decimalExponent) {
  68             this.significand = significand;
  69             this.binaryExponent = binaryExponent;
  70             this.decimalExponent = decimalExponent;
  71         }
  72     }
  73 
  74     static private final CachedPower[] kCachedPowers = {
  75             new CachedPower(0xfa8fd5a0081c0288L, -1220, -348),
  76             new CachedPower(0xbaaee17fa23ebf76L, -1193, -340),
  77             new CachedPower(0x8b16fb203055ac76L, -1166, -332),
  78             new CachedPower(0xcf42894a5dce35eaL, -1140, -324),
  79             new CachedPower(0x9a6bb0aa55653b2dL, -1113, -316),
  80             new CachedPower(0xe61acf033d1a45dfL, -1087, -308),
  81             new CachedPower(0xab70fe17c79ac6caL, -1060, -300),
  82             new CachedPower(0xff77b1fcbebcdc4fL, -1034, -292),
  83             new CachedPower(0xbe5691ef416bd60cL, -1007, -284),
  84             new CachedPower(0x8dd01fad907ffc3cL, -980, -276),
  85             new CachedPower(0xd3515c2831559a83L, -954, -268),
  86             new CachedPower(0x9d71ac8fada6c9b5L, -927, -260),
  87             new CachedPower(0xea9c227723ee8bcbL, -901, -252),
  88             new CachedPower(0xaecc49914078536dL, -874, -244),
  89             new CachedPower(0x823c12795db6ce57L, -847, -236),
  90             new CachedPower(0xc21094364dfb5637L, -821, -228),
  91             new CachedPower(0x9096ea6f3848984fL, -794, -220),
  92             new CachedPower(0xd77485cb25823ac7L, -768, -212),
  93             new CachedPower(0xa086cfcd97bf97f4L, -741, -204),
  94             new CachedPower(0xef340a98172aace5L, -715, -196),
  95             new CachedPower(0xb23867fb2a35b28eL, -688, -188),
  96             new CachedPower(0x84c8d4dfd2c63f3bL, -661, -180),
  97             new CachedPower(0xc5dd44271ad3cdbaL, -635, -172),
  98             new CachedPower(0x936b9fcebb25c996L, -608, -164),
  99             new CachedPower(0xdbac6c247d62a584L, -582, -156),
 100             new CachedPower(0xa3ab66580d5fdaf6L, -555, -148),
 101             new CachedPower(0xf3e2f893dec3f126L, -529, -140),
 102             new CachedPower(0xb5b5ada8aaff80b8L, -502, -132),
 103             new CachedPower(0x87625f056c7c4a8bL, -475, -124),
 104             new CachedPower(0xc9bcff6034c13053L, -449, -116),
 105             new CachedPower(0x964e858c91ba2655L, -422, -108),
 106             new CachedPower(0xdff9772470297ebdL, -396, -100),
 107             new CachedPower(0xa6dfbd9fb8e5b88fL, -369, -92),
 108             new CachedPower(0xf8a95fcf88747d94L, -343, -84),
 109             new CachedPower(0xb94470938fa89bcfL, -316, -76),
 110             new CachedPower(0x8a08f0f8bf0f156bL, -289, -68),
 111             new CachedPower(0xcdb02555653131b6L, -263, -60),
 112             new CachedPower(0x993fe2c6d07b7facL, -236, -52),
 113             new CachedPower(0xe45c10c42a2b3b06L, -210, -44),
 114             new CachedPower(0xaa242499697392d3L, -183, -36),
 115             new CachedPower(0xfd87b5f28300ca0eL, -157, -28),
 116             new CachedPower(0xbce5086492111aebL, -130, -20),
 117             new CachedPower(0x8cbccc096f5088ccL, -103, -12),
 118             new CachedPower(0xd1b71758e219652cL, -77, -4),
 119             new CachedPower(0x9c40000000000000L, -50, 4),
 120             new CachedPower(0xe8d4a51000000000L, -24, 12),
 121             new CachedPower(0xad78ebc5ac620000L, 3, 20),
 122             new CachedPower(0x813f3978f8940984L, 30, 28),
 123             new CachedPower(0xc097ce7bc90715b3L, 56, 36),
 124             new CachedPower(0x8f7e32ce7bea5c70L, 83, 44),
 125             new CachedPower(0xd5d238a4abe98068L, 109, 52),
 126             new CachedPower(0x9f4f2726179a2245L, 136, 60),
 127             new CachedPower(0xed63a231d4c4fb27L, 162, 68),
 128             new CachedPower(0xb0de65388cc8ada8L, 189, 76),
 129             new CachedPower(0x83c7088e1aab65dbL, 216, 84),
 130             new CachedPower(0xc45d1df942711d9aL, 242, 92),
 131             new CachedPower(0x924d692ca61be758L, 269, 100),
 132             new CachedPower(0xda01ee641a708deaL, 295, 108),
 133             new CachedPower(0xa26da3999aef774aL, 322, 116),
 134             new CachedPower(0xf209787bb47d6b85L, 348, 124),
 135             new CachedPower(0xb454e4a179dd1877L, 375, 132),
 136             new CachedPower(0x865b86925b9bc5c2L, 402, 140),
 137             new CachedPower(0xc83553c5c8965d3dL, 428, 148),
 138             new CachedPower(0x952ab45cfa97a0b3L, 455, 156),
 139             new CachedPower(0xde469fbd99a05fe3L, 481, 164),
 140             new CachedPower(0xa59bc234db398c25L, 508, 172),
 141             new CachedPower(0xf6c69a72a3989f5cL, 534, 180),
 142             new CachedPower(0xb7dcbf5354e9beceL, 561, 188),
 143             new CachedPower(0x88fcf317f22241e2L, 588, 196),
 144             new CachedPower(0xcc20ce9bd35c78a5L, 614, 204),
 145             new CachedPower(0x98165af37b2153dfL, 641, 212),
 146             new CachedPower(0xe2a0b5dc971f303aL, 667, 220),
 147             new CachedPower(0xa8d9d1535ce3b396L, 694, 228),
 148             new CachedPower(0xfb9b7cd9a4a7443cL, 720, 236),
 149             new CachedPower(0xbb764c4ca7a44410L, 747, 244),
 150             new CachedPower(0x8bab8eefb6409c1aL, 774, 252),
 151             new CachedPower(0xd01fef10a657842cL, 800, 260),
 152             new CachedPower(0x9b10a4e5e9913129L, 827, 268),
 153             new CachedPower(0xe7109bfba19c0c9dL, 853, 276),
 154             new CachedPower(0xac2820d9623bf429L, 880, 284),
 155             new CachedPower(0x80444b5e7aa7cf85L, 907, 292),
 156             new CachedPower(0xbf21e44003acdd2dL, 933, 300),
 157             new CachedPower(0x8e679c2f5e44ff8fL, 960, 308),
 158             new CachedPower(0xd433179d9c8cb841L, 986, 316),
 159             new CachedPower(0x9e19db92b4e31ba9L, 1013, 324),
 160             new CachedPower(0xeb96bf6ebadf77d9L, 1039, 332),
 161             new CachedPower(0xaf87023b9bf0ee6bL, 1066, 340)
 162     };
 163 
 164     static final int kCachedPowersOffset = 348;  // -1 * the first decimal_exponent.
 165     static final double kD_1_LOG2_10 = 0.30102999566398114;  //  1 / lg(10)
 166     // Difference between the decimal exponents in the table above.
 167     static final int kDecimalExponentDistance = 8;
 168     static final int kMinDecimalExponent = -348;
 169     static final int kMaxDecimalExponent = 340;
 170 
 171     static int getCachedPowerForBinaryExponentRange(
 172             final int min_exponent,
 173             final int max_exponent,
 174             final DiyFp power) {
 175         final int kQ = DiyFp.kSignificandSize;
 176         final double k = Math.ceil((min_exponent + kQ - 1) * kD_1_LOG2_10);
 177         final int index =
 178                 (kCachedPowersOffset + (int) k - 1) / kDecimalExponentDistance + 1;
 179         assert (0 <= index && index < kCachedPowers.length);
 180         final CachedPower cached_power = kCachedPowers[index];
 181         assert (min_exponent <= cached_power.binaryExponent);
 182         assert (cached_power.binaryExponent <= max_exponent);
 183         power.setF(cached_power.significand);
 184         power.setE(cached_power.binaryExponent);
 185         return cached_power.decimalExponent;
 186     }
 187 
 188 
 189     static int getCachedPowerForDecimalExponent(final int requested_exponent,
 190                                                 final DiyFp power) {
 191         assert (kMinDecimalExponent <= requested_exponent);
 192         assert (requested_exponent < kMaxDecimalExponent + kDecimalExponentDistance);
 193         final int index =
 194                 (requested_exponent + kCachedPowersOffset) / kDecimalExponentDistance;
 195         final CachedPower cached_power = kCachedPowers[index];
 196         power.setF(cached_power.significand);
 197         power.setE(cached_power.binaryExponent);
 198         final int found_exponent = cached_power.decimalExponent;
 199         assert (found_exponent <= requested_exponent);
 200         assert (requested_exponent < found_exponent + kDecimalExponentDistance);
 201         return cached_power.decimalExponent;
 202     }
 203 
 204 }