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
60// Dtoa implementation based on our own Bignum implementation, supporting
61// all conversion modes but slightly slower than the specialized implementations.
62class 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}
648