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 // Dtoa implementation based on our own Bignum implementation, supporting
  61 // all conversion modes but slightly slower than the specialized implementations.
  62 class BignumDtoa {
  63 
  64     private static int normalizedExponent(long significand, int exponent) {
  65         assert (significand != 0);
  66         while ((significand & IeeeDouble.kHiddenBit) == 0) {
  67             significand = significand << 1;
  68             exponent = exponent - 1;
  69         }
  70         return exponent;
  71     }
  72 
  73     // Converts the given double 'v' to ascii.
  74     // The result should be interpreted as buffer * 10^(point-length).
  75     // The buffer will be null-terminated.
  76     //
  77     // The input v must be > 0 and different from NaN, and Infinity.
  78     //
  79     // The output depends on the given mode:
  80     //  - SHORTEST: produce the least amount of digits for which the internal
  81     //   identity requirement is still satisfied. If the digits are printed
  82     //   (together with the correct exponent) then reading this number will give
  83     //   'v' again. The buffer will choose the representation that is closest to
  84     //   'v'. If there are two at the same distance, than the number is round up.
  85     //   In this mode the 'requested_digits' parameter is ignored.
  86     //  - FIXED: produces digits necessary to print a given number with
  87     //   'requested_digits' digits after the decimal point. The produced digits
  88     //   might be too short in which case the caller has to fill the gaps with '0's.
  89     //   Example: toFixed(0.001, 5) is allowed to return buffer="1", point=-2.
  90     //   Halfway cases are rounded up. The call toFixed(0.15, 2) thus returns
  91     //     buffer="2", point=0.
  92     //   Note: the length of the returned buffer has no meaning wrt the significance
  93     //   of its digits. That is, just because it contains '0's does not mean that
  94     //   any other digit would not satisfy the internal identity requirement.
  95     //  - PRECISION: produces 'requested_digits' where the first digit is not '0'.
  96     //   Even though the length of produced digits usually equals
  97     //   'requested_digits', the function is allowed to return fewer digits, in
  98     //   which case the caller has to fill the missing digits with '0's.
  99     //   Halfway cases are again rounded up.
 100     // 'BignumDtoa' expects the given buffer to be big enough to hold all digits
 101     // and a terminating null-character.
 102     static void bignumDtoa(final double v, final DtoaMode mode, final int requested_digits,
 103                     final DtoaBuffer buffer) {
 104         assert (v > 0);
 105         assert (!IeeeDouble.isSpecial(IeeeDouble.doubleToLong(v)));
 106         final long significand;
 107         final int exponent;
 108         final boolean lower_boundary_is_closer;
 109 
 110         final long l = IeeeDouble.doubleToLong(v);
 111         significand = IeeeDouble.significand(l);
 112         exponent = IeeeDouble.exponent(l);
 113         lower_boundary_is_closer = IeeeDouble.lowerBoundaryIsCloser(l);
 114 
 115         final boolean need_boundary_deltas = mode == DtoaMode.SHORTEST;
 116 
 117         final boolean is_even = (significand & 1) == 0;
 118         assert (significand != 0);
 119         final int normalizedExponent = normalizedExponent(significand, exponent);
 120         // estimated_power might be too low by 1.
 121         final int estimated_power = estimatePower(normalizedExponent);
 122 
 123         // Shortcut for Fixed.
 124         // The requested digits correspond to the digits after the point. If the
 125         // number is much too small, then there is no need in trying to get any
 126         // digits.
 127         if (mode == DtoaMode.FIXED && -estimated_power - 1 > requested_digits) {
 128             buffer.reset();
 129             // Set decimal-point to -requested_digits. This is what Gay does.
 130             // Note that it should not have any effect anyways since the string is
 131             // empty.
 132             buffer.decimalPoint = -requested_digits;
 133             return;
 134         }
 135 
 136         final Bignum numerator = new Bignum();
 137         final Bignum denominator = new Bignum();
 138         final Bignum delta_minus = new Bignum();
 139         final Bignum delta_plus = new Bignum();
 140         // Make sure the bignum can grow large enough. The smallest double equals
 141         // 4e-324. In this case the denominator needs fewer than 324*4 binary digits.
 142         // The maximum double is 1.7976931348623157e308 which needs fewer than
 143         // 308*4 binary digits.
 144         assert (Bignum.kMaxSignificantBits >= 324*4);
 145         initialScaledStartValues(significand, exponent, lower_boundary_is_closer,
 146                 estimated_power, need_boundary_deltas,
 147                 numerator, denominator,
 148                 delta_minus, delta_plus);
 149         // We now have v = (numerator / denominator) * 10^estimated_power.
 150         buffer.decimalPoint = fixupMultiply10(estimated_power, is_even,
 151                 numerator, denominator,
 152                 delta_minus, delta_plus);
 153         // We now have v = (numerator / denominator) * 10^(decimal_point-1), and
 154         //  1 <= (numerator + delta_plus) / denominator < 10
 155         switch (mode) {
 156             case SHORTEST:
 157                 generateShortestDigits(numerator, denominator,
 158                         delta_minus, delta_plus,
 159                         is_even, buffer);
 160                 break;
 161             case FIXED:
 162                 bignumToFixed(requested_digits,
 163                         numerator, denominator,
 164                         buffer);
 165                 break;
 166             case PRECISION:
 167                 generateCountedDigits(requested_digits,
 168                         numerator, denominator,
 169                         buffer);
 170                 break;
 171             default:
 172                 throw new RuntimeException();
 173         }
 174     }
 175 
 176 
 177     // The procedure starts generating digits from the left to the right and stops
 178     // when the generated digits yield the shortest decimal representation of v. A
 179     // decimal representation of v is a number lying closer to v than to any other
 180     // double, so it converts to v when read.
 181     //
 182     // This is true if d, the decimal representation, is between m- and m+, the
 183     // upper and lower boundaries. d must be strictly between them if !is_even.
 184     //           m- := (numerator - delta_minus) / denominator
 185     //           m+ := (numerator + delta_plus) / denominator
 186     //
 187     // Precondition: 0 <= (numerator+delta_plus) / denominator < 10.
 188     //   If 1 <= (numerator+delta_plus) / denominator < 10 then no leading 0 digit
 189     //   will be produced. This should be the standard precondition.
 190     static void generateShortestDigits(final Bignum numerator, final Bignum denominator,
 191                                        final Bignum delta_minus, Bignum delta_plus,
 192                                        final boolean is_even,
 193                                        final DtoaBuffer buffer) {
 194         // Small optimization: if delta_minus and delta_plus are the same just reuse
 195         // one of the two bignums.
 196         if (Bignum.equal(delta_minus, delta_plus)) {
 197             delta_plus = delta_minus;
 198         }
 199         for (;;) {
 200             final char digit;
 201             digit = numerator.divideModuloIntBignum(denominator);
 202             assert (digit <= 9);  // digit is a uint16_t and therefore always positive.
 203             // digit = numerator / denominator (integer division).
 204             // numerator = numerator % denominator.
 205             buffer.append((char) (digit + '0'));
 206 
 207             // Can we stop already?
 208             // If the remainder of the division is less than the distance to the lower
 209             // boundary we can stop. In this case we simply round down (discarding the
 210             // remainder).
 211             // Similarly we test if we can round up (using the upper boundary).
 212             final boolean in_delta_room_minus;
 213             final boolean in_delta_room_plus;
 214             if (is_even) {
 215                 in_delta_room_minus = Bignum.lessEqual(numerator, delta_minus);
 216             } else {
 217                 in_delta_room_minus = Bignum.less(numerator, delta_minus);
 218             }
 219             if (is_even) {
 220                 in_delta_room_plus =
 221                         Bignum.plusCompare(numerator, delta_plus, denominator) >= 0;
 222             } else {
 223                 in_delta_room_plus =
 224                         Bignum.plusCompare(numerator, delta_plus, denominator) > 0;
 225             }
 226             if (!in_delta_room_minus && !in_delta_room_plus) {
 227                 // Prepare for next iteration.
 228                 numerator.times10();
 229                 delta_minus.times10();
 230                 // We optimized delta_plus to be equal to delta_minus (if they share the
 231                 // same value). So don't multiply delta_plus if they point to the same
 232                 // object.
 233                 if (delta_minus != delta_plus) {
 234                     delta_plus.times10();
 235                 }
 236             } else if (in_delta_room_minus && in_delta_room_plus) {
 237                 // Let's see if 2*numerator < denominator.
 238                 // If yes, then the next digit would be < 5 and we can round down.
 239                 final int compare = Bignum.plusCompare(numerator, numerator, denominator);
 240                 if (compare < 0) {
 241                     // Remaining digits are less than .5. -> Round down (== do nothing).
 242                 } else if (compare > 0) {
 243                     // Remaining digits are more than .5 of denominator. -> Round up.
 244                     // Note that the last digit could not be a '9' as otherwise the whole
 245                     // loop would have stopped earlier.
 246                     // We still have an assert here in case the preconditions were not
 247                     // satisfied.
 248                     assert (buffer.chars[buffer.length - 1] != '9');
 249                     buffer.chars[buffer.length - 1]++;
 250                 } else {
 251                     // Halfway case.
 252                     // TODO(floitsch): need a way to solve half-way cases.
 253                     //   For now let's round towards even (since this is what Gay seems to
 254                     //   do).
 255 
 256                     if ((buffer.chars[buffer.length - 1] - '0') % 2 == 0) {
 257                         // Round down => Do nothing.
 258                     } else {
 259                         assert (buffer.chars[buffer.length - 1] != '9');
 260                         buffer.chars[buffer.length - 1]++;
 261                     }
 262                 }
 263                 return;
 264             } else if (in_delta_room_minus) {
 265                 // Round down (== do nothing).
 266                 return;
 267             } else {  // in_delta_room_plus
 268                 // Round up.
 269                 // Note again that the last digit could not be '9' since this would have
 270                 // stopped the loop earlier.
 271                 // We still have an ASSERT here, in case the preconditions were not
 272                 // satisfied.
 273                 assert (buffer.chars[buffer.length -1] != '9');
 274                 buffer.chars[buffer.length - 1]++;
 275                 return;
 276             }
 277         }
 278     }
 279 
 280 
 281     // Let v = numerator / denominator < 10.
 282     // Then we generate 'count' digits of d = x.xxxxx... (without the decimal point)
 283     // from left to right. Once 'count' digits have been produced we decide wether
 284     // to round up or down. Remainders of exactly .5 round upwards. Numbers such
 285     // as 9.999999 propagate a carry all the way, and change the
 286     // exponent (decimal_point), when rounding upwards.
 287     static void generateCountedDigits(final int count,
 288                                       final Bignum numerator, final Bignum denominator,
 289                                       final DtoaBuffer buffer) {
 290         assert (count >= 0);
 291         for (int i = 0; i < count - 1; ++i) {
 292             final char digit;
 293             digit = numerator.divideModuloIntBignum(denominator);
 294             assert (digit <= 9);  // digit is a uint16_t and therefore always positive.
 295             // digit = numerator / denominator (integer division).
 296             // numerator = numerator % denominator.
 297             buffer.chars[i] = (char)(digit + '0');
 298             // Prepare for next iteration.
 299             numerator.times10();
 300         }
 301         // Generate the last digit.
 302         char digit;
 303         digit = numerator.divideModuloIntBignum(denominator);
 304         if (Bignum.plusCompare(numerator, numerator, denominator) >= 0) {
 305             digit++;
 306         }
 307         assert (digit <= 10);
 308         buffer.chars[count - 1] = (char) (digit + '0');
 309         // Correct bad digits (in case we had a sequence of '9's). Propagate the
 310         // carry until we hat a non-'9' or til we reach the first digit.
 311         for (int i = count - 1; i > 0; --i) {
 312             if (buffer.chars[i] != '0' + 10) break;
 313             buffer.chars[i] = '0';
 314             buffer.chars[i - 1]++;
 315         }
 316         if (buffer.chars[0] == '0' + 10) {
 317             // Propagate a carry past the top place.
 318             buffer.chars[0] = '1';
 319             buffer.decimalPoint++;
 320         }
 321         buffer.length = count;
 322     }
 323 
 324 
 325     // Generates 'requested_digits' after the decimal point. It might omit
 326     // trailing '0's. If the input number is too small then no digits at all are
 327     // generated (ex.: 2 fixed digits for 0.00001).
 328     //
 329     // Input verifies:  1 <= (numerator + delta) / denominator < 10.
 330     static void bignumToFixed(final int requested_digits,
 331                               final Bignum numerator, final Bignum denominator,
 332                               final DtoaBuffer buffer) {
 333         // Note that we have to look at more than just the requested_digits, since
 334         // a number could be rounded up. Example: v=0.5 with requested_digits=0.
 335         // Even though the power of v equals 0 we can't just stop here.
 336         if (-buffer.decimalPoint > requested_digits) {
 337             // The number is definitively too small.
 338             // Ex: 0.001 with requested_digits == 1.
 339             // Set decimal-decimalPoint to -requested_digits. This is what Gay does.
 340             // Note that it should not have any effect anyways since the string is
 341             // empty.
 342             buffer.decimalPoint = -requested_digits;
 343             buffer.length = 0;
 344             // return;
 345         } else if (-buffer.decimalPoint == requested_digits) {
 346             // We only need to verify if the number rounds down or up.
 347             // Ex: 0.04 and 0.06 with requested_digits == 1.
 348             assert (buffer.decimalPoint == -requested_digits);
 349             // Initially the fraction lies in range (1, 10]. Multiply the denominator
 350             // by 10 so that we can compare more easily.
 351             denominator.times10();
 352             if (Bignum.plusCompare(numerator, numerator, denominator) >= 0) {
 353                 // If the fraction is >= 0.5 then we have to include the rounded
 354                 // digit.
 355                 buffer.chars[0] = '1';
 356                 buffer.length = 1;
 357                 buffer.decimalPoint++;
 358             } else {
 359                 // Note that we caught most of similar cases earlier.
 360                 buffer.length = 0;
 361             }
 362             // return;
 363         } else {
 364             // The requested digits correspond to the digits after the point.
 365             // The variable 'needed_digits' includes the digits before the point.
 366             final int needed_digits = buffer.decimalPoint + requested_digits;
 367             generateCountedDigits(needed_digits,
 368                     numerator, denominator,
 369                     buffer);
 370         }
 371     }
 372 
 373 
 374     // Returns an estimation of k such that 10^(k-1) <= v < 10^k where
 375     // v = f * 2^exponent and 2^52 <= f < 2^53.
 376     // v is hence a normalized double with the given exponent. The output is an
 377     // approximation for the exponent of the decimal approimation .digits * 10^k.
 378     //
 379     // The result might undershoot by 1 in which case 10^k <= v < 10^k+1.
 380     // Note: this property holds for v's upper boundary m+ too.
 381     //    10^k <= m+ < 10^k+1.
 382     //   (see explanation below).
 383     //
 384     // Examples:
 385     //  EstimatePower(0)   => 16
 386     //  EstimatePower(-52) => 0
 387     //
 388     // Note: e >= 0 => EstimatedPower(e) > 0. No similar claim can be made for e<0.
 389     static int estimatePower(final int exponent) {
 390         // This function estimates log10 of v where v = f*2^e (with e == exponent).
 391         // Note that 10^floor(log10(v)) <= v, but v <= 10^ceil(log10(v)).
 392         // Note that f is bounded by its container size. Let p = 53 (the double's
 393         // significand size). Then 2^(p-1) <= f < 2^p.
 394         //
 395         // Given that log10(v) == log2(v)/log2(10) and e+(len(f)-1) is quite close
 396         // to log2(v) the function is simplified to (e+(len(f)-1)/log2(10)).
 397         // The computed number undershoots by less than 0.631 (when we compute log3
 398         // and not log10).
 399         //
 400         // Optimization: since we only need an approximated result this computation
 401         // can be performed on 64 bit integers. On x86/x64 architecture the speedup is
 402         // not really measurable, though.
 403         //
 404         // Since we want to avoid overshooting we decrement by 1e10 so that
 405         // floating-point imprecisions don't affect us.
 406         //
 407         // Explanation for v's boundary m+: the computation takes advantage of
 408         // the fact that 2^(p-1) <= f < 2^p. Boundaries still satisfy this requirement
 409         // (even for denormals where the delta can be much more important).
 410 
 411         final double k1Log10 = 0.30102999566398114;  // 1/lg(10)
 412 
 413         // For doubles len(f) == 53 (don't forget the hidden bit).
 414         final int kSignificandSize = IeeeDouble.kSignificandSize;
 415         final double estimate = Math.ceil((exponent + kSignificandSize - 1) * k1Log10 - 1e-10);
 416         return (int) estimate;
 417     }
 418 
 419 
 420     // See comments for InitialScaledStartValues.
 421     static void initialScaledStartValuesPositiveExponent(
 422             final long significand, final int exponent,
 423             final int estimated_power, final boolean need_boundary_deltas,
 424             final Bignum numerator, final Bignum denominator,
 425             final Bignum delta_minus, final Bignum delta_plus) {
 426         // A positive exponent implies a positive power.
 427         assert (estimated_power >= 0);
 428         // Since the estimated_power is positive we simply multiply the denominator
 429         // by 10^estimated_power.
 430 
 431         // numerator = v.
 432         numerator.assignUInt64(significand);
 433         numerator.shiftLeft(exponent);
 434         // denominator = 10^estimated_power.
 435         denominator.assignPowerUInt16(10, estimated_power);
 436 
 437         if (need_boundary_deltas) {
 438             // Introduce a common denominator so that the deltas to the boundaries are
 439             // integers.
 440             denominator.shiftLeft(1);
 441             numerator.shiftLeft(1);
 442             // Let v = f * 2^e, then m+ - v = 1/2 * 2^e; With the common
 443             // denominator (of 2) delta_plus equals 2^e.
 444             delta_plus.assignUInt16((char) 1);
 445             delta_plus.shiftLeft(exponent);
 446             // Same for delta_minus. The adjustments if f == 2^p-1 are done later.
 447             delta_minus.assignUInt16((char) 1);
 448             delta_minus.shiftLeft(exponent);
 449         }
 450     }
 451 
 452 
 453     // See comments for InitialScaledStartValues
 454     static void initialScaledStartValuesNegativeExponentPositivePower(
 455             final long significand, final int exponent,
 456             final int estimated_power, final boolean need_boundary_deltas,
 457             final Bignum numerator, final Bignum denominator,
 458             final Bignum delta_minus, final Bignum delta_plus) {
 459         // v = f * 2^e with e < 0, and with estimated_power >= 0.
 460         // This means that e is close to 0 (have a look at how estimated_power is
 461         // computed).
 462 
 463         // numerator = significand
 464         //  since v = significand * 2^exponent this is equivalent to
 465         //  numerator = v * / 2^-exponent
 466         numerator.assignUInt64(significand);
 467         // denominator = 10^estimated_power * 2^-exponent (with exponent < 0)
 468         denominator.assignPowerUInt16(10, estimated_power);
 469         denominator.shiftLeft(-exponent);
 470 
 471         if (need_boundary_deltas) {
 472             // Introduce a common denominator so that the deltas to the boundaries are
 473             // integers.
 474             denominator.shiftLeft(1);
 475             numerator.shiftLeft(1);
 476             // Let v = f * 2^e, then m+ - v = 1/2 * 2^e; With the common
 477             // denominator (of 2) delta_plus equals 2^e.
 478             // Given that the denominator already includes v's exponent the distance
 479             // to the boundaries is simply 1.
 480             delta_plus.assignUInt16((char) 1);
 481             // Same for delta_minus. The adjustments if f == 2^p-1 are done later.
 482             delta_minus.assignUInt16((char) 1);
 483         }
 484     }
 485 
 486 
 487     // See comments for InitialScaledStartValues
 488     static void initialScaledStartValuesNegativeExponentNegativePower(
 489             final long significand, final int exponent,
 490             final int estimated_power, final boolean need_boundary_deltas,
 491             final Bignum numerator, final Bignum denominator,
 492             final Bignum delta_minus, final Bignum delta_plus) {
 493         // Instead of multiplying the denominator with 10^estimated_power we
 494         // multiply all values (numerator and deltas) by 10^-estimated_power.
 495 
 496         // Use numerator as temporary container for power_ten.
 497         final Bignum power_ten = numerator;
 498         power_ten.assignPowerUInt16(10, -estimated_power);
 499 
 500         if (need_boundary_deltas) {
 501             // Since power_ten == numerator we must make a copy of 10^estimated_power
 502             // before we complete the computation of the numerator.
 503             // delta_plus = delta_minus = 10^estimated_power
 504             delta_plus.assignBignum(power_ten);
 505             delta_minus.assignBignum(power_ten);
 506         }
 507 
 508         // numerator = significand * 2 * 10^-estimated_power
 509         //  since v = significand * 2^exponent this is equivalent to
 510         // numerator = v * 10^-estimated_power * 2 * 2^-exponent.
 511         // Remember: numerator has been abused as power_ten. So no need to assign it
 512         //  to itself.
 513         assert (numerator == power_ten);
 514         numerator.multiplyByUInt64(significand);
 515 
 516         // denominator = 2 * 2^-exponent with exponent < 0.
 517         denominator.assignUInt16((char) 1);
 518         denominator.shiftLeft(-exponent);
 519 
 520         if (need_boundary_deltas) {
 521             // Introduce a common denominator so that the deltas to the boundaries are
 522             // integers.
 523             numerator.shiftLeft(1);
 524             denominator.shiftLeft(1);
 525             // With this shift the boundaries have their correct value, since
 526             // delta_plus = 10^-estimated_power, and
 527             // delta_minus = 10^-estimated_power.
 528             // These assignments have been done earlier.
 529             // The adjustments if f == 2^p-1 (lower boundary is closer) are done later.
 530         }
 531     }
 532 
 533 
 534     // Let v = significand * 2^exponent.
 535     // Computes v / 10^estimated_power exactly, as a ratio of two bignums, numerator
 536     // and denominator. The functions GenerateShortestDigits and
 537     // GenerateCountedDigits will then convert this ratio to its decimal
 538     // representation d, with the required accuracy.
 539     // Then d * 10^estimated_power is the representation of v.
 540     // (Note: the fraction and the estimated_power might get adjusted before
 541     // generating the decimal representation.)
 542     //
 543     // The initial start values consist of:
 544     //  - a scaled numerator: s.t. numerator/denominator == v / 10^estimated_power.
 545     //  - a scaled (common) denominator.
 546     //  optionally (used by GenerateShortestDigits to decide if it has the shortest
 547     //  decimal converting back to v):
 548     //  - v - m-: the distance to the lower boundary.
 549     //  - m+ - v: the distance to the upper boundary.
 550     //
 551     // v, m+, m-, and therefore v - m- and m+ - v all share the same denominator.
 552     //
 553     // Let ep == estimated_power, then the returned values will satisfy:
 554     //  v / 10^ep = numerator / denominator.
 555     //  v's boundarys m- and m+:
 556     //    m- / 10^ep == v / 10^ep - delta_minus / denominator
 557     //    m+ / 10^ep == v / 10^ep + delta_plus / denominator
 558     //  Or in other words:
 559     //    m- == v - delta_minus * 10^ep / denominator;
 560     //    m+ == v + delta_plus * 10^ep / denominator;
 561     //
 562     // Since 10^(k-1) <= v < 10^k    (with k == estimated_power)
 563     //  or       10^k <= v < 10^(k+1)
 564     //  we then have 0.1 <= numerator/denominator < 1
 565     //           or    1 <= numerator/denominator < 10
 566     //
 567     // It is then easy to kickstart the digit-generation routine.
 568     //
 569     // The boundary-deltas are only filled if the mode equals BIGNUM_DTOA_SHORTEST
 570     // or BIGNUM_DTOA_SHORTEST_SINGLE.
 571 
 572     static void initialScaledStartValues(final long significand,
 573                                          final int exponent,
 574                                          final boolean lower_boundary_is_closer,
 575                                          final int estimated_power,
 576                                          final boolean need_boundary_deltas,
 577                                          final Bignum numerator,
 578                                          final Bignum denominator,
 579                                          final Bignum delta_minus,
 580                                          final Bignum delta_plus) {
 581         if (exponent >= 0) {
 582             initialScaledStartValuesPositiveExponent(
 583                     significand, exponent, estimated_power, need_boundary_deltas,
 584                     numerator, denominator, delta_minus, delta_plus);
 585         } else if (estimated_power >= 0) {
 586             initialScaledStartValuesNegativeExponentPositivePower(
 587                     significand, exponent, estimated_power, need_boundary_deltas,
 588                     numerator, denominator, delta_minus, delta_plus);
 589         } else {
 590             initialScaledStartValuesNegativeExponentNegativePower(
 591                     significand, exponent, estimated_power, need_boundary_deltas,
 592                     numerator, denominator, delta_minus, delta_plus);
 593         }
 594 
 595         if (need_boundary_deltas && lower_boundary_is_closer) {
 596             // The lower boundary is closer at half the distance of "normal" numbers.
 597             // Increase the common denominator and adapt all but the delta_minus.
 598             denominator.shiftLeft(1);  // *2
 599             numerator.shiftLeft(1);    // *2
 600             delta_plus.shiftLeft(1);   // *2
 601         }
 602     }
 603 
 604 
 605     // This routine multiplies numerator/denominator so that its values lies in the
 606     // range 1-10. That is after a call to this function we have:
 607     //    1 <= (numerator + delta_plus) /denominator < 10.
 608     // Let numerator the input before modification and numerator' the argument
 609     // after modification, then the output-parameter decimal_point is such that
 610     //  numerator / denominator * 10^estimated_power ==
 611     //    numerator' / denominator' * 10^(decimal_point - 1)
 612     // In some cases estimated_power was too low, and this is already the case. We
 613     // then simply adjust the power so that 10^(k-1) <= v < 10^k (with k ==
 614     // estimated_power) but do not touch the numerator or denominator.
 615     // Otherwise the routine multiplies the numerator and the deltas by 10.
 616     static int fixupMultiply10(final int estimated_power, final boolean is_even,
 617                                 final Bignum numerator, final Bignum denominator,
 618                                 final Bignum delta_minus, final Bignum delta_plus) {
 619         final boolean in_range;
 620         final int decimal_point;
 621         if (is_even) {
 622             // For IEEE doubles half-way cases (in decimal system numbers ending with 5)
 623             // are rounded to the closest floating-point number with even significand.
 624             in_range = Bignum.plusCompare(numerator, delta_plus, denominator) >= 0;
 625         } else {
 626             in_range = Bignum.plusCompare(numerator, delta_plus, denominator) > 0;
 627         }
 628         if (in_range) {
 629             // Since numerator + delta_plus >= denominator we already have
 630             // 1 <= numerator/denominator < 10. Simply update the estimated_power.
 631             decimal_point = estimated_power + 1;
 632         } else {
 633             decimal_point = estimated_power;
 634             numerator.times10();
 635             if (Bignum.equal(delta_minus, delta_plus)) {
 636                 delta_minus.times10();
 637                 delta_plus.assignBignum(delta_minus);
 638             } else {
 639                 delta_minus.times10();
 640                 delta_plus.times10();
 641             }
 642         }
 643         return decimal_point;
 644     }
 645 
 646 
 647 }