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 class FixedDtoa { 61 62 // Represents a 128bit type. This class should be replaced by a native type on 63 // platforms that support 128bit integers. 64 static class UInt128 { 65 66 private static final long kMask32 = 0xFFFFFFFFL; 67 // Value == (high_bits_ << 64) + low_bits_ 68 private long high_bits_; 69 private long low_bits_; 70 71 UInt128(final long high_bits, final long low_bits) { 72 this.high_bits_ = high_bits; 73 this.low_bits_ = low_bits; 74 } 75 76 void multiply(final int multiplicand) { 77 long accumulator; 78 79 accumulator = (low_bits_ & kMask32) * multiplicand; 80 long part = accumulator & kMask32; 81 accumulator >>>= 32; 82 accumulator = accumulator + (low_bits_ >>> 32) * multiplicand; 83 low_bits_ = (accumulator << 32) + part; 84 accumulator >>>= 32; 85 accumulator = accumulator + (high_bits_ & kMask32) * multiplicand; 86 part = accumulator & kMask32; 87 accumulator >>>= 32; 88 accumulator = accumulator + (high_bits_ >>> 32) * multiplicand; 89 high_bits_ = (accumulator << 32) + part; 90 assert ((accumulator >>> 32) == 0); 91 } 92 93 void shift(final int shift_amount) { 94 assert (-64 <= shift_amount && shift_amount <= 64); 95 if (shift_amount == 0) { 96 return; 97 } else if (shift_amount == -64) { 98 high_bits_ = low_bits_; 99 low_bits_ = 0; 100 } else if (shift_amount == 64) { 101 low_bits_ = high_bits_; 102 high_bits_ = 0; 103 } else if (shift_amount <= 0) { 104 high_bits_ <<= -shift_amount; 105 high_bits_ += low_bits_ >>> (64 + shift_amount); 106 low_bits_ <<= -shift_amount; 107 } else { 108 low_bits_ >>>= shift_amount; 109 low_bits_ += high_bits_ << (64 - shift_amount); 110 high_bits_ >>>= shift_amount; 111 } 112 } 113 114 // Modifies *this to *this MOD (2^power). 115 // Returns *this DIV (2^power). 116 int divModPowerOf2(final int power) { 117 if (power >= 64) { 118 final int result = (int) (high_bits_ >>> (power - 64)); 119 high_bits_ -= (long) (result) << (power - 64); 120 return result; 121 } else { 122 final long part_low = low_bits_ >>> power; 123 final long part_high = high_bits_ << (64 - power); 124 final int result = (int) (part_low + part_high); 125 high_bits_ = 0; 126 low_bits_ -= part_low << power; 127 return result; 128 } 129 } 130 131 boolean isZero() { 132 return high_bits_ == 0 && low_bits_ == 0; 133 } 134 135 int bitAt(final int position) { 136 if (position >= 64) { 137 return (int) (high_bits_ >>> (position - 64)) & 1; 138 } else { 139 return (int) (low_bits_ >>> position) & 1; 140 } 141 } 142 143 }; 144 145 146 static final int kDoubleSignificandSize = 53; // Includes the hidden bit. 147 148 149 static void fillDigits32FixedLength(int number, final int requested_length, 150 final DtoaBuffer buffer) { 151 for (int i = requested_length - 1; i >= 0; --i) { 152 buffer.chars[buffer.length + i] = (char) ('0' + Integer.remainderUnsigned(number, 10)); 153 number = Integer.divideUnsigned(number, 10); 154 } 155 buffer.length += requested_length; 156 } 157 158 159 static void fillDigits32(int number, final DtoaBuffer buffer) { 160 int number_length = 0; 161 // We fill the digits in reverse order and exchange them afterwards. 162 while (number != 0) { 163 final int digit = Integer.remainderUnsigned(number, 10); 164 number = Integer.divideUnsigned(number, 10); 165 buffer.chars[buffer.length + number_length] = (char) ('0' + digit); 166 number_length++; 167 } 168 // Exchange the digits. 169 int i = buffer.length; 170 int j = buffer.length + number_length - 1; 171 while (i < j) { 172 final char tmp = buffer.chars[i]; 173 buffer.chars[i] = buffer.chars[j]; 174 buffer.chars[j] = tmp; 175 i++; 176 j--; 177 } 178 buffer.length += number_length; 179 } 180 181 182 static void fillDigits64FixedLength(long number, final DtoaBuffer buffer) { 183 final int kTen7 = 10000000; 184 // For efficiency cut the number into 3 uint32_t parts, and print those. 185 final int part2 = (int) Long.remainderUnsigned(number, kTen7); 186 number = Long.divideUnsigned(number, kTen7); 187 final int part1 = (int) Long.remainderUnsigned(number, kTen7); 188 final int part0 = (int) Long.divideUnsigned(number, kTen7); 189 190 fillDigits32FixedLength(part0, 3, buffer); 191 fillDigits32FixedLength(part1, 7, buffer); 192 fillDigits32FixedLength(part2, 7, buffer); 193 } 194 195 196 static void FillDigits64(long number, final DtoaBuffer buffer) { 197 final int kTen7 = 10000000; 198 // For efficiency cut the number into 3 uint32_t parts, and print those. 199 final int part2 = (int) Long.remainderUnsigned(number, kTen7); 200 number = Long.divideUnsigned(number, kTen7); 201 final int part1 = (int) Long.remainderUnsigned(number, kTen7); 202 final int part0 = (int) Long.divideUnsigned(number, kTen7); 203 204 if (part0 != 0) { 205 fillDigits32(part0, buffer); 206 fillDigits32FixedLength(part1, 7, buffer); 207 fillDigits32FixedLength(part2, 7, buffer); 208 } else if (part1 != 0) { 209 fillDigits32(part1, buffer); 210 fillDigits32FixedLength(part2, 7, buffer); 211 } else { 212 fillDigits32(part2, buffer); 213 } 214 } 215 216 217 static void roundUp(final DtoaBuffer buffer) { 218 // An empty buffer represents 0. 219 if (buffer.length == 0) { 220 buffer.chars[0] = '1'; 221 buffer.decimalPoint = 1; 222 buffer.length = 1; 223 return; 224 } 225 // Round the last digit until we either have a digit that was not '9' or until 226 // we reached the first digit. 227 buffer.chars[buffer.length - 1]++; 228 for (int i = buffer.length - 1; i > 0; --i) { 229 if (buffer.chars[i] != '0' + 10) { 230 return; 231 } 232 buffer.chars[i] = '0'; 233 buffer.chars[i - 1]++; 234 } 235 // If the first digit is now '0' + 10, we would need to set it to '0' and add 236 // a '1' in front. However we reach the first digit only if all following 237 // digits had been '9' before rounding up. Now all trailing digits are '0' and 238 // we simply switch the first digit to '1' and update the decimal-point 239 // (indicating that the point is now one digit to the right). 240 if (buffer.chars[0] == '0' + 10) { 241 buffer.chars[0] = '1'; 242 buffer.decimalPoint++; 243 } 244 } 245 246 247 // The given fractionals number represents a fixed-point number with binary 248 // point at bit (-exponent). 249 // Preconditions: 250 // -128 <= exponent <= 0. 251 // 0 <= fractionals * 2^exponent < 1 252 // The buffer holds the result. 253 // The function will round its result. During the rounding-process digits not 254 // generated by this function might be updated, and the decimal-point variable 255 // might be updated. If this function generates the digits 99 and the buffer 256 // already contained "199" (thus yielding a buffer of "19999") then a 257 // rounding-up will change the contents of the buffer to "20000". 258 static void fillFractionals(long fractionals, final int exponent, 259 final int fractional_count, final DtoaBuffer buffer) { 260 assert (-128 <= exponent && exponent <= 0); 261 // 'fractionals' is a fixed-decimalPoint number, with binary decimalPoint at bit 262 // (-exponent). Inside the function the non-converted remainder of fractionals 263 // is a fixed-decimalPoint number, with binary decimalPoint at bit 'decimalPoint'. 264 if (-exponent <= 64) { 265 // One 64 bit number is sufficient. 266 assert (fractionals >>> 56 == 0); 267 int point = -exponent; 268 for (int i = 0; i < fractional_count; ++i) { 269 if (fractionals == 0) break; 270 // Instead of multiplying by 10 we multiply by 5 and adjust the point 271 // location. This way the fractionals variable will not overflow. 272 // Invariant at the beginning of the loop: fractionals < 2^point. 273 // Initially we have: point <= 64 and fractionals < 2^56 274 // After each iteration the point is decremented by one. 275 // Note that 5^3 = 125 < 128 = 2^7. 276 // Therefore three iterations of this loop will not overflow fractionals 277 // (even without the subtraction at the end of the loop body). At this 278 // time point will satisfy point <= 61 and therefore fractionals < 2^point 279 // and any further multiplication of fractionals by 5 will not overflow. 280 fractionals *= 5; 281 point--; 282 final int digit = (int) (fractionals >>> point); 283 assert (digit <= 9); 284 buffer.chars[buffer.length] = (char) ('0' + digit); 285 buffer.length++; 286 fractionals -= (long) (digit) << point; 287 } 288 // If the first bit after the point is set we have to round up. 289 assert (fractionals == 0 || point - 1 >= 0); 290 if ((fractionals != 0) && ((fractionals >>> (point - 1)) & 1) == 1) { 291 roundUp(buffer); 292 } 293 } else { // We need 128 bits. 294 assert (64 < -exponent && -exponent <= 128); 295 final UInt128 fractionals128 = new UInt128(fractionals, 0); 296 fractionals128.shift(-exponent - 64); 297 int point = 128; 298 for (int i = 0; i < fractional_count; ++i) { 299 if (fractionals128.isZero()) break; 300 // As before: instead of multiplying by 10 we multiply by 5 and adjust the 301 // point location. 302 // This multiplication will not overflow for the same reasons as before. 303 fractionals128.multiply(5); 304 point--; 305 final int digit = fractionals128.divModPowerOf2(point); 306 assert (digit <= 9); 307 buffer.chars[buffer.length] = (char) ('0' + digit); 308 buffer.length++; 309 } 310 if (fractionals128.bitAt(point - 1) == 1) { 311 roundUp(buffer); 312 } 313 } 314 } 315 316 317 // Removes leading and trailing zeros. 318 // If leading zeros are removed then the decimal point position is adjusted. 319 static void trimZeros(final DtoaBuffer buffer) { 320 while (buffer.length > 0 && buffer.chars[buffer.length - 1] == '0') { 321 buffer.length--; 322 } 323 int first_non_zero = 0; 324 while (first_non_zero < buffer.length && buffer.chars[first_non_zero] == '0') { 325 first_non_zero++; 326 } 327 if (first_non_zero != 0) { 328 for (int i = first_non_zero; i < buffer.length; ++i) { 329 buffer.chars[i - first_non_zero] = buffer.chars[i]; 330 } 331 buffer.length -= first_non_zero; 332 buffer.decimalPoint -= first_non_zero; 333 } 334 } 335 336 337 static boolean fastFixedDtoa(final double v, 338 final int fractional_count, 339 final DtoaBuffer buffer) { 340 final long kMaxUInt32 = 0xFFFFFFFFL; 341 final long l = IeeeDouble.doubleToLong(v); 342 long significand = IeeeDouble.significand(l); 343 final int exponent = IeeeDouble.exponent(l); 344 // v = significand * 2^exponent (with significand a 53bit integer). 345 // If the exponent is larger than 20 (i.e. we may have a 73bit number) then we 346 // don't know how to compute the representation. 2^73 ~= 9.5*10^21. 347 // If necessary this limit could probably be increased, but we don't need 348 // more. 349 if (exponent > 20) return false; 350 if (fractional_count > 20) return false; 351 // At most kDoubleSignificandSize bits of the significand are non-zero. 352 // Given a 64 bit integer we have 11 0s followed by 53 potentially non-zero 353 // bits: 0..11*..0xxx..53*..xx 354 if (exponent + kDoubleSignificandSize > 64) { 355 // The exponent must be > 11. 356 // 357 // We know that v = significand * 2^exponent. 358 // And the exponent > 11. 359 // We simplify the task by dividing v by 10^17. 360 // The quotient delivers the first digits, and the remainder fits into a 64 361 // bit number. 362 // Dividing by 10^17 is equivalent to dividing by 5^17*2^17. 363 final long kFive17 = 0xB1A2BC2EC5L; // 5^17 364 long divisor = kFive17; 365 final int divisor_power = 17; 366 long dividend = significand; 367 final int quotient; 368 final long remainder; 369 // Let v = f * 2^e with f == significand and e == exponent. 370 // Then need q (quotient) and r (remainder) as follows: 371 // v = q * 10^17 + r 372 // f * 2^e = q * 10^17 + r 373 // f * 2^e = q * 5^17 * 2^17 + r 374 // If e > 17 then 375 // f * 2^(e-17) = q * 5^17 + r/2^17 376 // else 377 // f = q * 5^17 * 2^(17-e) + r/2^e 378 if (exponent > divisor_power) { 379 // We only allow exponents of up to 20 and therefore (17 - e) <= 3 380 dividend <<= exponent - divisor_power; 381 quotient = (int) Long.divideUnsigned(dividend, divisor); 382 remainder = Long.remainderUnsigned(dividend, divisor) << divisor_power; 383 } else { 384 divisor <<= divisor_power - exponent; 385 quotient = (int) Long.divideUnsigned(dividend, divisor); 386 remainder = Long.remainderUnsigned(dividend, divisor) << exponent; 387 } 388 fillDigits32(quotient, buffer); 389 fillDigits64FixedLength(remainder, buffer); 390 buffer.decimalPoint = buffer.length; 391 } else if (exponent >= 0) { 392 // 0 <= exponent <= 11 393 significand <<= exponent; 394 FillDigits64(significand, buffer); 395 buffer.decimalPoint = buffer.length; 396 } else if (exponent > -kDoubleSignificandSize) { 397 // We have to cut the number. 398 final long integrals = significand >>> -exponent; 399 final long fractionals = significand - (integrals << -exponent); 400 if (Long.compareUnsigned(integrals, kMaxUInt32) > 0) { 401 FillDigits64(integrals, buffer); 402 } else { 403 fillDigits32((int) (integrals), buffer); 404 } 405 buffer.decimalPoint = buffer.length; 406 fillFractionals(fractionals, exponent, fractional_count, buffer); 407 } else if (exponent < -128) { 408 // This configuration (with at most 20 digits) means that all digits must be 409 // 0. 410 assert (fractional_count <= 20); 411 buffer.reset(); 412 buffer.decimalPoint = -fractional_count; 413 } else { 414 buffer.decimalPoint = 0; 415 fillFractionals(significand, exponent, fractional_count, buffer); 416 } 417 trimZeros(buffer); 418 if (buffer.length == 0) { 419 // The string is empty and the decimal_point thus has no importance. Mimick 420 // Gay's dtoa and and set it to -fractional_count. 421 buffer.decimalPoint = -fractional_count; 422 } 423 return true; 424 } 425 426 }