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 58package jdk.nashorn.internal.runtime.doubleconv; 59 60class 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 if (((fractionals >>> (point - 1)) & 1) == 1) { 290 roundUp(buffer); 291 } 292 } else { // We need 128 bits. 293 assert (64 < -exponent && -exponent <= 128); 294 final UInt128 fractionals128 = new UInt128(fractionals, 0); 295 fractionals128.shift(-exponent - 64); 296 int point = 128; 297 for (int i = 0; i < fractional_count; ++i) { 298 if (fractionals128.isZero()) break; 299 // As before: instead of multiplying by 10 we multiply by 5 and adjust the 300 // point location. 301 // This multiplication will not overflow for the same reasons as before. 302 fractionals128.multiply(5); 303 point--; 304 final int digit = fractionals128.divModPowerOf2(point); 305 assert (digit <= 9); 306 buffer.chars[buffer.length] = (char) ('0' + digit); 307 buffer.length++; 308 } 309 if (fractionals128.bitAt(point - 1) == 1) { 310 roundUp(buffer); 311 } 312 } 313 } 314 315 316 // Removes leading and trailing zeros. 317 // If leading zeros are removed then the decimal point position is adjusted. 318 static void trimZeros(final DtoaBuffer buffer) { 319 while (buffer.length > 0 && buffer.chars[buffer.length - 1] == '0') { 320 buffer.length--; 321 } 322 int first_non_zero = 0; 323 while (first_non_zero < buffer.length && buffer.chars[first_non_zero] == '0') { 324 first_non_zero++; 325 } 326 if (first_non_zero != 0) { 327 for (int i = first_non_zero; i < buffer.length; ++i) { 328 buffer.chars[i - first_non_zero] = buffer.chars[i]; 329 } 330 buffer.length -= first_non_zero; 331 buffer.decimalPoint -= first_non_zero; 332 } 333 } 334 335 336 static boolean fastFixedDtoa(final double v, 337 final int fractional_count, 338 final DtoaBuffer buffer) { 339 final long kMaxUInt32 = 0xFFFFFFFFL; 340 final long l = IeeeDouble.doubleToLong(v); 341 long significand = IeeeDouble.significand(l); 342 final int exponent = IeeeDouble.exponent(l); 343 // v = significand * 2^exponent (with significand a 53bit integer). 344 // If the exponent is larger than 20 (i.e. we may have a 73bit number) then we 345 // don't know how to compute the representation. 2^73 ~= 9.5*10^21. 346 // If necessary this limit could probably be increased, but we don't need 347 // more. 348 if (exponent > 20) return false; 349 if (fractional_count > 20) return false; 350 // At most kDoubleSignificandSize bits of the significand are non-zero. 351 // Given a 64 bit integer we have 11 0s followed by 53 potentially non-zero 352 // bits: 0..11*..0xxx..53*..xx 353 if (exponent + kDoubleSignificandSize > 64) { 354 // The exponent must be > 11. 355 // 356 // We know that v = significand * 2^exponent. 357 // And the exponent > 11. 358 // We simplify the task by dividing v by 10^17. 359 // The quotient delivers the first digits, and the remainder fits into a 64 360 // bit number. 361 // Dividing by 10^17 is equivalent to dividing by 5^17*2^17. 362 final long kFive17 = 0xB1A2BC2EC5L; // 5^17 363 long divisor = kFive17; 364 final int divisor_power = 17; 365 long dividend = significand; 366 final int quotient; 367 final long remainder; 368 // Let v = f * 2^e with f == significand and e == exponent. 369 // Then need q (quotient) and r (remainder) as follows: 370 // v = q * 10^17 + r 371 // f * 2^e = q * 10^17 + r 372 // f * 2^e = q * 5^17 * 2^17 + r 373 // If e > 17 then 374 // f * 2^(e-17) = q * 5^17 + r/2^17 375 // else 376 // f = q * 5^17 * 2^(17-e) + r/2^e 377 if (exponent > divisor_power) { 378 // We only allow exponents of up to 20 and therefore (17 - e) <= 3 379 dividend <<= exponent - divisor_power; 380 quotient = (int) Long.divideUnsigned(dividend, divisor); 381 remainder = Long.remainderUnsigned(dividend, divisor) << divisor_power; 382 } else { 383 divisor <<= divisor_power - exponent; 384 quotient = (int) Long.divideUnsigned(dividend, divisor); 385 remainder = Long.remainderUnsigned(dividend, divisor) << exponent; 386 } 387 fillDigits32(quotient, buffer); 388 fillDigits64FixedLength(remainder, buffer); 389 buffer.decimalPoint = buffer.length; 390 } else if (exponent >= 0) { 391 // 0 <= exponent <= 11 392 significand <<= exponent; 393 FillDigits64(significand, buffer); 394 buffer.decimalPoint = buffer.length; 395 } else if (exponent > -kDoubleSignificandSize) { 396 // We have to cut the number. 397 final long integrals = significand >>> -exponent; 398 final long fractionals = significand - (integrals << -exponent); 399 if (Long.compareUnsigned(integrals, kMaxUInt32) > 0) { 400 FillDigits64(integrals, buffer); 401 } else { 402 fillDigits32((int) (integrals), buffer); 403 } 404 buffer.decimalPoint = buffer.length; 405 fillFractionals(fractionals, exponent, fractional_count, buffer); 406 } else if (exponent < -128) { 407 // This configuration (with at most 20 digits) means that all digits must be 408 // 0. 409 assert (fractional_count <= 20); 410 buffer.reset(); 411 buffer.decimalPoint = -fractional_count; 412 } else { 413 buffer.decimalPoint = 0; 414 fillFractionals(significand, exponent, fractional_count, buffer); 415 } 416 trimZeros(buffer); 417 if (buffer.length == 0) { 418 // The string is empty and the decimal_point thus has no importance. Mimick 419 // Gay's dtoa and and set it to -fractional_count. 420 buffer.decimalPoint = -fractional_count; 421 } 422 return true; 423 } 424 425} 426