1 /*
2  * Hunt - A refined core library for D programming language.
3  *
4  * Copyright (C) 2018-2019 HuntLabs
5  *
6  * Website: https://www.huntlabs.net/
7  *
8  * Licensed under the Apache-2.0 License.
9  *
10  */
11 
12 module hunt.math.BigDecimal;
13 
14 import std.conv;
15 import hunt.util.StringBuilder;
16 import hunt.math.BigInteger;
17 import hunt.Exceptions;
18 import hunt.Integer;
19 import hunt.Long;
20 import hunt.math.Helper;
21 import hunt.Number;
22 
23 /**
24  * Immutable, arbitrary-precision signed decimal numbers.  A
25  * {@code BigDecimal} consists of an arbitrary precision integer
26  * <i>unscaled value</i> and a 32-bit integer <i>scale</i>.  If zero
27  * or positive, the scale is the number of digits to the right of the
28  * decimal point.  If negative, the unscaled value of the number is
29  * multiplied by ten to the power of the negation of the scale.  The
30  * value of the number represented by the {@code BigDecimal} is
31  * therefore <code>(unscaledValue &times; 10!(sup)-scale</sup>)</code>.
32  *
33  * <p>The {@code BigDecimal} class provides operations for
34  * arithmetic, scale manipulation, rounding, comparison, hashing, and
35  * format conversion.  The {@link #toString} method provides a
36  * canonical representation of a {@code BigDecimal}.
37  *
38  * <p>The {@code BigDecimal} class gives its user complete control
39  * over rounding behavior.  If no rounding mode is specified and the
40  * exact result cannot be represented, an exception is thrown;
41  * otherwise, calculations can be carried out to a chosen precision
42  * and rounding mode by supplying an appropriate {@link MathContext}
43  * object to the operation.  In either case, eight <em>rounding
44  * modes</em> are provided for the control of rounding.  Using the
45  * integer fields in this class (such as {@link #ROUND_HALF_UP}) to
46  * represent rounding mode is deprecated; the enumeration values
47  * of the {@code RoundingMode} {@code enum}, (such as {@link
48  * RoundingMode#HALF_UP}) should be used instead.
49  *
50  * <p>When a {@code MathContext} object is supplied with a precision
51  * setting of 0 (for example, {@link MathContext#UNLIMITED}),
52  * arithmetic operations are exact, as are the arithmetic methods
53  * which take no {@code MathContext} object.  (This is the only
54  * behavior that was supported in releases prior to 5.)  As a
55  * corollary of computing the exact result, the rounding mode setting
56  * of a {@code MathContext} object with a precision setting of 0 is
57  * not used and thus irrelevant.  In the case of divide, the exact
58  * quotient could have an infinitely long decimal expansion; for
59  * example, 1 divided by 3.  If the quotient has a nonterminating
60  * decimal expansion and the operation is specified to return an exact
61  * result, an {@code ArithmeticException} is thrown.  Otherwise, the
62  * exact result of the division is returned, as done for other
63  * operations.
64  *
65  * <p>When the precision setting is not 0, the rules of
66  * {@code BigDecimal} arithmetic are broadly compatible with selected
67  * modes of operation of the arithmetic defined in ANSI X3.274-1996
68  * and ANSI X3.274-1996/AM 1-2000 (section 7.4).  Unlike those
69  * standards, {@code BigDecimal} includes many rounding modes, which
70  * were mandatory for division in {@code BigDecimal} releases prior
71  * to 5.  Any conflicts between these ANSI standards and the
72  * {@code BigDecimal} specification are resolved in favor of
73  * {@code BigDecimal}.
74  *
75  * <p>Since the same numerical value can have different
76  * representations (with different scales), the rules of arithmetic
77  * and rounding must specify both the numerical result and the scale
78  * used in the result's representation.
79  *
80  *
81  * <p>In general the rounding modes and precision setting determine
82  * how operations return results with a limited number of digits when
83  * the exact result has more digits (perhaps infinitely many in the
84  * case of division and square root) than the number of digits returned.
85  *
86  * First, the
87  * total number of digits to return is specified by the
88  * {@code MathContext}'s {@code precision} setting; this determines
89  * the result's <i>precision</i>.  The digit count starts from the
90  * leftmost nonzero digit of the exact result.  The rounding mode
91  * determines how any discarded trailing digits affect the returned
92  * result.
93  *
94  * <p>For all arithmetic operators , the operation is carried out as
95  * though an exact intermediate result were first calculated and then
96  * rounded to the number of digits specified by the precision setting
97  * (if necessary), using the selected rounding mode.  If the exact
98  * result is not returned, some digit positions of the exact result
99  * are discarded.  When rounding increases the magnitude of the
100  * returned result, it is possible for a new digit position to be
101  * created by a carry propagating to a leading {@literal "9"} digit.
102  * For example, rounding the value 999.9 to three digits rounding up
103  * would be numerically equal to one thousand, represented as
104  * 100&times;10!(sup)1</sup>.  In such cases, the new {@literal "1"} is
105  * the leading digit position of the returned result.
106  *
107  * <p>Besides a logical exact result, each arithmetic operation has a
108  * preferred scale for representing a result.  The preferred
109  * scale for each operation is listed in the table below.
110  *
111  * <table class="striped" style="text-align:left">
112  * <caption>Preferred Scales for Results of Arithmetic Operations
113  * </caption>
114  * <thead>
115  * <tr><th scope="col">Operation</th><th scope="col">Preferred Scale of Result</th></tr>
116  * </thead>
117  * <tbody>
118  * <tr><th scope="row">Add</th><td>max(addend.scale(), augend.scale())</td>
119  * <tr><th scope="row">Subtract</th><td>max(minuend.scale(), subtrahend.scale())</td>
120  * <tr><th scope="row">Multiply</th><td>multiplier.scale() + multiplicand.scale()</td>
121  * <tr><th scope="row">Divide</th><td>dividend.scale() - divisor.scale()</td>
122  * <tr><th scope="row">Square root</th><td>radicand.scale()/2</td>
123  * </tbody>
124  * </table>
125  *
126  * These scales are the ones used by the methods which return exact
127  * arithmetic results; except that an exact divide may have to use a
128  * larger scale since the exact result may have more digits.  For
129  * example, {@code 1/32} is {@code 0.03125}.
130  *
131  * <p>Before rounding, the scale of the logical exact intermediate
132  * result is the preferred scale for that operation.  If the exact
133  * numerical result cannot be represented in {@code precision}
134  * digits, rounding selects the set of digits to return and the scale
135  * of the result is reduced from the scale of the intermediate result
136  * to the least scale which can represent the {@code precision}
137  * digits actually returned.  If the exact result can be represented
138  * with at most {@code precision} digits, the representation
139  * of the result with the scale closest to the preferred scale is
140  * returned.  In particular, an exactly representable quotient may be
141  * represented in fewer than {@code precision} digits by removing
142  * trailing zeros and decreasing the scale.  For example, rounding to
143  * three digits using the {@linkplain RoundingMode#FLOOR floor}
144  * rounding mode, <br>
145  *
146  * {@code 19/100 = 0.19   // integer=19,  scale=2} <br>
147  *
148  * but!(br)
149  *
150  * {@code 21/110 = 0.190  // integer=190, scale=3} <br>
151  *
152  * <p>Note that for add, subtract, and multiply, the reduction in
153  * scale will equal the number of digit positions of the exact result
154  * which are discarded. If the rounding causes a carry propagation to
155  * create a new high-order digit position, an additional digit of the
156  * result is discarded than when no new digit position is created.
157  *
158  * <p>Other methods may have slightly different rounding semantics.
159  * For example, the result of the {@code pow} method using the
160  * {@linkplain #pow(int, MathContext) specified algorithm} can
161  * occasionally differ from the rounded mathematical result by more
162  * than one unit in the last place, one <i>{@linkplain #ulp() ulp}</i>.
163  *
164  * <p>Two types of operations are provided for manipulating the scale
165  * of a {@code BigDecimal}: scaling/rounding operations and decimal
166  * point motion operations.  Scaling/rounding operations ({@link
167  * #setScale setScale} and {@link #round round}) return a
168  * {@code BigDecimal} whose value is approximately (or exactly) equal
169  * to that of the operand, but whose scale or precision is the
170  * specified value; that is, they increase or decrease the precision
171  * of the stored number with minimal effect on its value.  Decimal
172  * point motion operations ({@link #movePointLeft movePointLeft} and
173  * {@link #movePointRight movePointRight}) return a
174  * {@code BigDecimal} created from the operand by moving the decimal
175  * point a specified distance in the specified direction.
176  *
177  * <p>For the sake of brevity and clarity, pseudo-code is used
178  * throughout the descriptions of {@code BigDecimal} methods.  The
179  * pseudo-code expression {@code (i + j)} is shorthand for "a
180  * {@code BigDecimal} whose value is that of the {@code BigDecimal}
181  * {@code i} added to that of the {@code BigDecimal}
182  * {@code j}." The pseudo-code expression {@code (i == j)} is
183  * shorthand for "{@code true} if and only if the
184  * {@code BigDecimal} {@code i} represents the same value as the
185  * {@code BigDecimal} {@code j}." Other pseudo-code expressions
186  * are interpreted similarly.  Square brackets are used to represent
187  * the particular {@code BigInteger} and scale pair defining a
188  * {@code BigDecimal} value; for example [19, 2] is the
189  * {@code BigDecimal} numerically equal to 0.19 having a scale of 2.
190  *
191  *
192  * <p>All methods and constructors for this class throw
193  * {@code NullPointerException} when passed a {@code null} object
194  * reference for any input parameter.
195  *
196  * @apiNote Care should be exercised if {@code BigDecimal} objects
197  * are used as keys in a {@link java.util.SortedMap SortedMap} or
198  * elements in a {@link java.util.SortedSet SortedSet} since
199  * {@code BigDecimal}'s <i>natural ordering</i> is <em>inconsistent
200  * with equals</em>.  See {@link Comparable}, {@link
201  * java.util.SortedMap} or {@link java.util.SortedSet} for more
202  * information.
203  *
204  * @see     BigInteger
205  * @see     MathContext
206  * @see     RoundingMode
207  * @see     java.util.SortedMap
208  * @see     java.util.SortedSet
209  * @author  Josh Bloch
210  * @author  Mike Cowlishaw
211  * @author  Joseph D. Darcy
212  * @author  Sergey V. Kuksenko
213  */
214 class BigDecimal : Number
215 {
216     /**
217      * The unscaled value of this BigDecimal, as returned by {@link
218      * #unscaledValue}.
219      *
220      * @serial
221      * @see #unscaledValue
222      */
223     private BigInteger intVal;
224 
225     /**
226      * The scale of this BigDecimal, as returned by {@link #scale}.
227      *
228      * @serial
229      * @see #scale
230      */
231     private int _scale; // Note: this may have any value, so
232     // calculations must be done in longs
233 
234     /**
235      * The number of decimal digits in this BigDecimal, or 0 if the
236      * number of digits are not known (lookaside information).  If
237      * nonzero, the value is guaranteed correct.  Use the precision()
238      * method to obtain and set the value if it might be 0.  This
239      * field is mutable until set nonzero.
240      *
241      */
242     private int precision;
243 
244     //     /**
245     //      * Used to store the canonical string representation, if computed.
246     //      */
247     //     private /*transient*/ string stringCache;
248 
249     //     /**
250     //      * Sentinel value for {@link #intCompact} indicating the
251     //      * significand information is only available from {@code intVal}.
252     //      */
253     __gshared long INFLATED;
254 
255     //     private static final BigInteger INFLATED_BIGINT = BigInteger.valueOf(INFLATED);
256 
257     /**
258      * If the absolute value of the significand of this BigDecimal is
259      * less than or equal to {@code Long.MAX_VALUE}, the value can be
260      * compactly stored in this field and used in computations.
261      */
262     private long intCompact;
263 
264     // All 18-digit base ten strings fit into a long; not all 19-digit
265     // strings will
266     private static int MAX_COMPACT_DIGITS = 18;
267 
268     shared static this()
269     {
270         INFLATED = Long.MIN_VALUE;
271         ZERO_THROUGH_TEN = [new BigDecimal(BigInteger.ZERO, 0, 0, 1),
272             new BigDecimal(BigInteger.ONE, 1, 0, 1), new BigDecimal(BigInteger.TWO,
273                     2, 0, 1), new BigDecimal(BigInteger.valueOf(3), 3, 0, 1),
274             new BigDecimal(BigInteger.valueOf(4), 4, 0, 1), new BigDecimal(BigInteger.valueOf(5),
275                     5, 0, 1), new BigDecimal(BigInteger.valueOf(6), 6, 0, 1),
276             new BigDecimal(BigInteger.valueOf(7), 7, 0, 1), new BigDecimal(BigInteger.valueOf(8),
277                     8, 0, 1), new BigDecimal(BigInteger.valueOf(9), 9, 0, 1),
278             new BigDecimal(BigInteger.TEN, 10, 0, 2),];
279 
280         ONE = ZERO_THROUGH_TEN[1];
281         ZERO = ZERO_THROUGH_TEN[0];
282     }
283 
284     //     /* Appease the serialization gods */
285     //     private static final long serialVersionUID = 6108874887143696463L;
286 
287     //     private static final ThreadLocal!(StringBuilderHelper)
288     //         threadLocalStringBuilderHelper = new ThreadLocal!(StringBuilderHelper)() {
289     //         @Override
290     //         protected StringBuilderHelper initialValue() {
291     //             return new StringBuilderHelper();
292     //         }
293     //     };
294 
295     //     // Cache of common small BigDecimal values.
296     __gshared BigDecimal[] ZERO_THROUGH_TEN;
297 
298     //     // Cache of zero scaled by 0 - 15
299     //     private static final BigDecimal[] ZERO_SCALED_BY = {
300     //         ZERO_THROUGH_TEN[0],
301     //         new BigDecimal(BigInteger.ZERO, 0, 1, 1),
302     //         new BigDecimal(BigInteger.ZERO, 0, 2, 1),
303     //         new BigDecimal(BigInteger.ZERO, 0, 3, 1),
304     //         new BigDecimal(BigInteger.ZERO, 0, 4, 1),
305     //         new BigDecimal(BigInteger.ZERO, 0, 5, 1),
306     //         new BigDecimal(BigInteger.ZERO, 0, 6, 1),
307     //         new BigDecimal(BigInteger.ZERO, 0, 7, 1),
308     //         new BigDecimal(BigInteger.ZERO, 0, 8, 1),
309     //         new BigDecimal(BigInteger.ZERO, 0, 9, 1),
310     //         new BigDecimal(BigInteger.ZERO, 0, 10, 1),
311     //         new BigDecimal(BigInteger.ZERO, 0, 11, 1),
312     //         new BigDecimal(BigInteger.ZERO, 0, 12, 1),
313     //         new BigDecimal(BigInteger.ZERO, 0, 13, 1),
314     //         new BigDecimal(BigInteger.ZERO, 0, 14, 1),
315     //         new BigDecimal(BigInteger.ZERO, 0, 15, 1),
316     //     };
317 
318     //     // Half of Long.MIN_VALUE & Long.MAX_VALUE.
319     //     private static final long HALF_LONG_MAX_VALUE = Long.MAX_VALUE / 2;
320     //     private static final long HALF_LONG_MIN_VALUE = Long.MIN_VALUE / 2;
321 
322     //     // Constants
323     //     /**
324     //      * The value 0, with a scale of 0.
325     //      *
326     //      */
327     __gshared BigDecimal ZERO;
328 
329     //     /**
330     //      * The value 1, with a scale of 0.
331     //      *
332     //      */
333     __gshared BigDecimal ONE;
334 
335     //     /**
336     //      * The value 10, with a scale of 0.
337     //      *
338     //      */
339     //     static final BigDecimal TEN =
340     //         ZERO_THROUGH_TEN[10];
341 
342     //     /**
343     //      * The value 0.1, with a scale of 1.
344     //      */
345     //     private static final BigDecimal ONE_TENTH = valueOf(1L, 1);
346 
347     //     /**
348     //      * The value 0.5, with a scale of 1.
349     //      */
350     //     private static final BigDecimal ONE_HALF = valueOf(5L, 1);
351 
352     //     // Constructors
353 
354     /**
355      * Trusted package private constructor.
356      * Trusted simply means if val is INFLATED, intVal could not be null and
357      * if intVal is null, val could not be INFLATED.
358      */
359     this(BigInteger intVal, long val, int scale, int prec)
360     {
361         this._scale = scale;
362         this.precision = prec;
363         this.intCompact = val;
364         this.intVal = intVal;
365     }
366 
367     //     /**
368     //      * Translates a character array representation of a
369     //      * {@code BigDecimal} into a {@code BigDecimal}, accepting the
370     //      * same sequence of characters as the {@link #BigDecimal(string)}
371     //      * constructor, while allowing a sub-array to be specified.
372     //      *
373     //      * @implNote If the sequence of characters is already available
374     //      * within a character array, using this constructor is faster than
375     //      * converting the {@code char} array to string and using the
376     //      * {@code BigDecimal(string)} constructor.
377     //      *
378     //      * @param  in {@code char} array that is the source of characters.
379     //      * @param  offset first character in the array to inspect.
380     //      * @param  len number of characters to consider.
381     //      * @throws NumberFormatException if {@code in} is not a valid
382     //      *         representation of a {@code BigDecimal} or the defined subarray
383     //      *         is not wholly within {@code in}.
384     //      */
385     //     BigDecimal(char[] in, int offset, int len) {
386     //         this(in,offset,len,MathContext.UNLIMITED);
387     //     }
388 
389     //     /**
390     //      * Translates a character array representation of a
391     //      * {@code BigDecimal} into a {@code BigDecimal}, accepting the
392     //      * same sequence of characters as the {@link #BigDecimal(string)}
393     //      * constructor, while allowing a sub-array to be specified and
394     //      * with rounding according to the context settings.
395     //      *
396     //      * @implNote If the sequence of characters is already available
397     //      * within a character array, using this constructor is faster than
398     //      * converting the {@code char} array to string and using the
399     //      * {@code BigDecimal(string)} constructor.
400     //      *
401     //      * @param  in {@code char} array that is the source of characters.
402     //      * @param  offset first character in the array to inspect.
403     //      * @param  len number of characters to consider.
404     //      * @param  mc the context to use.
405     //      * @throws ArithmeticException if the result is inexact but the
406     //      *         rounding mode is {@code UNNECESSARY}.
407     //      * @throws NumberFormatException if {@code in} is not a valid
408     //      *         representation of a {@code BigDecimal} or the defined subarray
409     //      *         is not wholly within {@code in}.
410     //      */
411     //     BigDecimal(char[] in, int offset, int len, MathContext mc) {
412     //         // protect against huge length.
413     //         if (offset + len > in.length || offset < 0)
414     //             throw new NumberFormatException("Bad offset or len arguments for char[] input.");
415     //         // This is the primary string to BigDecimal constructor; all
416     //         // incoming strings end up here; it uses explicit (inline)
417     //         // parsing for speed and generates at most one intermediate
418     //         // (temporary) object (a char[] array) for non-compact case.
419 
420     //         // Use locals for all fields values until completion
421     //         int prec = 0;                 // record precision value
422     //         int scl = 0;                  // record scale value
423     //         long rs = 0;                  // the compact value in long
424     //         BigInteger rb = null;         // the inflated value in BigInteger
425     //         // use array bounds checking to handle too-long, len == 0,
426     //         // bad offset, etc.
427     //         try {
428     //             // handle the sign
429     //             bool isneg = false;          // assume positive
430     //             if (in[offset] == '-') {
431     //                 isneg = true;               // leading minus means negative
432     //                 offset++;
433     //                 len--;
434     //             } else if (in[offset] == '+') { // leading + allowed
435     //                 offset++;
436     //                 len--;
437     //             }
438 
439     //             // should now be at numeric part of the significand
440     //             bool dot = false;             // true when there is a '.'
441     //             long exp = 0;                    // exponent
442     //             char c;                          // current character
443     //             bool isCompact = (len <= MAX_COMPACT_DIGITS);
444     //             // integer significand array & idx is the index to it. The array
445     //             // is ONLY used when we can't use a compact representation.
446     //             int idx = 0;
447     //             if (isCompact) {
448     //                 // First compact case, we need not to preserve the character
449     //                 // and we can just compute the value in place.
450     //                 for (; len > 0; offset++, len--) {
451     //                     c = in[offset];
452     //                     if ((c == '0')) { // have zero
453     //                         if (prec == 0)
454     //                             prec = 1;
455     //                         else if (rs != 0) {
456     //                             rs *= 10;
457     //                             ++prec;
458     //                         } // else digit is a redundant leading zero
459     //                         if (dot)
460     //                             ++scl;
461     //                     } else if ((c >= '1' && c <= '9')) { // have digit
462     //                         int digit = c - '0';
463     //                         if (prec != 1 || rs != 0)
464     //                             ++prec; // prec unchanged if preceded by 0s
465     //                         rs = rs * 10 + digit;
466     //                         if (dot)
467     //                             ++scl;
468     //                     } else if (c == '.') {   // have dot
469     //                         // have dot
470     //                         if (dot) // two dots
471     //                             throw new NumberFormatException("Character array"
472     //                                 ~ " contains more than one decimal point.");
473     //                         dot = true;
474     //                     } else if (Character.isDigit(c)) { // slow path
475     //                         int digit = Character.digit(c, 10);
476     //                         if (digit == 0) {
477     //                             if (prec == 0)
478     //                                 prec = 1;
479     //                             else if (rs != 0) {
480     //                                 rs *= 10;
481     //                                 ++prec;
482     //                             } // else digit is a redundant leading zero
483     //                         } else {
484     //                             if (prec != 1 || rs != 0)
485     //                                 ++prec; // prec unchanged if preceded by 0s
486     //                             rs = rs * 10 + digit;
487     //                         }
488     //                         if (dot)
489     //                             ++scl;
490     //                     } else if ((c == 'e') || (c == 'E')) {
491     //                         exp = parseExp(in, offset, len);
492     //                         // Next test is required for backwards compatibility
493     //                         if ((int) exp != exp) // overflow
494     //                             throw new NumberFormatException("Exponent overflow.");
495     //                         break; // [saves a test]
496     //                     } else {
497     //                         throw new NumberFormatException("Character " ~ c
498     //                             ~ " is neither a decimal digit number, decimal point, nor"
499     //                             ~ " \"e\" notation exponential mark.");
500     //                     }
501     //                 }
502     //                 if (prec == 0) // no digits found
503     //                     throw new NumberFormatException("No digits found.");
504     //                 // Adjust scale if exp is not zero.
505     //                 if (exp != 0) { // had significant exponent
506     //                     scl = adjustScale(scl, exp);
507     //                 }
508     //                 rs = isneg ? -rs : rs;
509     //                 int mcp = mc.precision;
510     //                 int drop = prec - mcp; // prec has range [1, MAX_INT], mcp has range [0, MAX_INT];
511     //                                        // therefore, this subtract cannot overflow
512     //                 if (mcp > 0 && drop > 0) {  // do rounding
513     //                     while (drop > 0) {
514     //                         scl = checkScaleNonZero((long) scl - drop);
515     //                         rs = divideAndRound(rs, LONG_TEN_POWERS_TABLE[drop], mc.roundingMode.oldMode);
516     //                         prec = longDigitLength(rs);
517     //                         drop = prec - mcp;
518     //                     }
519     //                 }
520     //             } else {
521     //                 char coeff[] = new char[len];
522     //                 for (; len > 0; offset++, len--) {
523     //                     c = in[offset];
524     //                     // have digit
525     //                     if ((c >= '0' && c <= '9') || Character.isDigit(c)) {
526     //                         // First compact case, we need not to preserve the character
527     //                         // and we can just compute the value in place.
528     //                         if (c == '0' || Character.digit(c, 10) == 0) {
529     //                             if (prec == 0) {
530     //                                 coeff[idx] = c;
531     //                                 prec = 1;
532     //                             } else if (idx != 0) {
533     //                                 coeff[idx++] = c;
534     //                                 ++prec;
535     //                             } // else c must be a redundant leading zero
536     //                         } else {
537     //                             if (prec != 1 || idx != 0)
538     //                                 ++prec; // prec unchanged if preceded by 0s
539     //                             coeff[idx++] = c;
540     //                         }
541     //                         if (dot)
542     //                             ++scl;
543     //                         continue;
544     //                     }
545     //                     // have dot
546     //                     if (c == '.') {
547     //                         // have dot
548     //                         if (dot) // two dots
549     //                             throw new NumberFormatException("Character array"
550     //                                 ~ " contains more than one decimal point.");
551     //                         dot = true;
552     //                         continue;
553     //                     }
554     //                     // exponent expected
555     //                     if ((c != 'e') && (c != 'E'))
556     //                         throw new NumberFormatException("Character array"
557     //                             ~ " is missing \"e\" notation exponential mark.");
558     //                     exp = parseExp(in, offset, len);
559     //                     // Next test is required for backwards compatibility
560     //                     if ((int) exp != exp) // overflow
561     //                         throw new NumberFormatException("Exponent overflow.");
562     //                     break; // [saves a test]
563     //                 }
564     //                 // here when no characters left
565     //                 if (prec == 0) // no digits found
566     //                     throw new NumberFormatException("No digits found.");
567     //                 // Adjust scale if exp is not zero.
568     //                 if (exp != 0) { // had significant exponent
569     //                     scl = adjustScale(scl, exp);
570     //                 }
571     //                 // Remove leading zeros from precision (digits count)
572     //                 rb = new BigInteger(coeff, isneg ? -1 : 1, prec);
573     //                 rs = compactValFor(rb);
574     //                 int mcp = mc.precision;
575     //                 if (mcp > 0 && (prec > mcp)) {
576     //                     if (rs == INFLATED) {
577     //                         int drop = prec - mcp;
578     //                         while (drop > 0) {
579     //                             scl = checkScaleNonZero((long) scl - drop);
580     //                             rb = divideAndRoundByTenPow(rb, drop, mc.roundingMode.oldMode);
581     //                             rs = compactValFor(rb);
582     //                             if (rs != INFLATED) {
583     //                                 prec = longDigitLength(rs);
584     //                                 break;
585     //                             }
586     //                             prec = bigDigitLength(rb);
587     //                             drop = prec - mcp;
588     //                         }
589     //                     }
590     //                     if (rs != INFLATED) {
591     //                         int drop = prec - mcp;
592     //                         while (drop > 0) {
593     //                             scl = checkScaleNonZero((long) scl - drop);
594     //                             rs = divideAndRound(rs, LONG_TEN_POWERS_TABLE[drop], mc.roundingMode.oldMode);
595     //                             prec = longDigitLength(rs);
596     //                             drop = prec - mcp;
597     //                         }
598     //                         rb = null;
599     //                     }
600     //                 }
601     //             }
602     //         } catch (ArrayIndexOutOfBoundsException | NegativeArraySizeException e) {
603     //             NumberFormatException nfe = new NumberFormatException();
604     //             nfe.initCause(e);
605     //             throw nfe;
606     //         }
607     //         this.scale = scl;
608     //         this.precision = prec;
609     //         this.intCompact = rs;
610     //         this.intVal = rb;
611     //     }
612 
613     private int adjustScale(int scl, long exp)
614     {
615         long adjustedScale = scl - exp;
616         if (adjustedScale > Integer.MAX_VALUE || adjustedScale < Integer.MIN_VALUE)
617             throw new Exception("NumberFormat : Scale out of range.");
618         scl = cast(int) adjustedScale;
619         return scl;
620     }
621 
622     //     /*
623     //      * parse exponent
624     //      */
625     //     private static long parseExp(char[] in, int offset, int len){
626     //         long exp = 0;
627     //         offset++;
628     //         char c = in[offset];
629     //         len--;
630     //         bool negexp = (c == '-');
631     //         // optional sign
632     //         if (negexp || c == '+') {
633     //             offset++;
634     //             c = in[offset];
635     //             len--;
636     //         }
637     //         if (len <= 0) // no exponent digits
638     //             throw new NumberFormatException("No exponent digits.");
639     //         // skip leading zeros in the exponent
640     //         while (len > 10 && (c=='0' || (Character.digit(c, 10) == 0))) {
641     //             offset++;
642     //             c = in[offset];
643     //             len--;
644     //         }
645     //         if (len > 10) // too many nonzero exponent digits
646     //             throw new NumberFormatException("Too many nonzero exponent digits.");
647     //         // c now holds first digit of exponent
648     //         for (;; len--) {
649     //             int v;
650     //             if (c >= '0' && c <= '9') {
651     //                 v = c - '0';
652     //             } else {
653     //                 v = Character.digit(c, 10);
654     //                 if (v < 0) // not a digit
655     //                     throw new NumberFormatException("Not a digit.");
656     //             }
657     //             exp = exp * 10 + v;
658     //             if (len == 1)
659     //                 break; // that was final character
660     //             offset++;
661     //             c = in[offset];
662     //         }
663     //         if (negexp) // apply sign
664     //             exp = -exp;
665     //         return exp;
666     //     }
667 
668     //     /**
669     //      * Translates a character array representation of a
670     //      * {@code BigDecimal} into a {@code BigDecimal}, accepting the
671     //      * same sequence of characters as the {@link #BigDecimal(string)}
672     //      * constructor.
673     //      *
674     //      * @implNote If the sequence of characters is already available
675     //      * as a character array, using this constructor is faster than
676     //      * converting the {@code char} array to string and using the
677     //      * {@code BigDecimal(string)} constructor.
678     //      *
679     //      * @param in {@code char} array that is the source of characters.
680     //      * @throws NumberFormatException if {@code in} is not a valid
681     //      *         representation of a {@code BigDecimal}.
682     //      */
683     this(char[] inp)
684     {
685         //this(in, 0, in.length);
686     }
687 
688     //     /**
689     //      * Translates a character array representation of a
690     //      * {@code BigDecimal} into a {@code BigDecimal}, accepting the
691     //      * same sequence of characters as the {@link #BigDecimal(string)}
692     //      * constructor and with rounding according to the context
693     //      * settings.
694     //      *
695     //      * @implNote If the sequence of characters is already available
696     //      * as a character array, using this constructor is faster than
697     //      * converting the {@code char} array to string and using the
698     //      * {@code BigDecimal(string)} constructor.
699     //      *
700     //      * @param  in {@code char} array that is the source of characters.
701     //      * @param  mc the context to use.
702     //      * @throws ArithmeticException if the result is inexact but the
703     //      *         rounding mode is {@code UNNECESSARY}.
704     //      * @throws NumberFormatException if {@code in} is not a valid
705     //      *         representation of a {@code BigDecimal}.
706     //      */
707     // BigDecimal(char[] in, MathContext mc) {
708     //     this(in, 0, in.length, mc);
709     // }
710 
711     /**
712      * Translates the string representation of a {@code BigDecimal}
713      * into a {@code BigDecimal}.  The string representation consists
714      * of an optional sign, {@code '+'} (<code> '&#92;u002B'</code>) or
715      * {@code '-'} (<code>'&#92;u002D'</code>), followed by a sequence of
716      * zero or more decimal digits ("the integer"), optionally
717      * followed by a fraction, optionally followed by an exponent.
718      *
719      * <p>The fraction consists of a decimal point followed by zero
720      * or more decimal digits.  The string must contain at least one
721      * digit in either the integer or the fraction.  The number formed
722      * by the sign, the integer and the fraction is referred to as the
723      * <i>significand</i>.
724      *
725      * <p>The exponent consists of the character {@code 'e'}
726      * (<code>'&#92;u0065'</code>) or {@code 'E'} (<code>'&#92;u0045'</code>)
727      * followed by one or more decimal digits.  The value of the
728      * exponent must lie between -{@link Integer#MAX_VALUE} ({@link
729      * Integer#MIN_VALUE}+1) and {@link Integer#MAX_VALUE}, inclusive.
730      *
731      * <p>More formally, the strings this constructor accepts are
732      * described by the following grammar:
733      * <blockquote>
734      * <dl>
735      * <dt><i>BigDecimalString:</i>
736      * <dd><i>Sign!(sub)opt</sub> Significand Exponent!(sub)opt</sub></i>
737      * <dt><i>Sign:</i>
738      * <dd>{@code +}
739      * <dd>{@code -}
740      * <dt><i>Significand:</i>
741      * <dd><i>IntegerPart</i> {@code .} <i>FractionPart!(sub)opt</sub></i>
742      * <dd>{@code .} <i>FractionPart</i>
743      * <dd><i>IntegerPart</i>
744      * <dt><i>IntegerPart:</i>
745      * <dd><i>Digits</i>
746      * <dt><i>FractionPart:</i>
747      * <dd><i>Digits</i>
748      * <dt><i>Exponent:</i>
749      * <dd><i>ExponentIndicator SignedInteger</i>
750      * <dt><i>ExponentIndicator:</i>
751      * <dd>{@code e}
752      * <dd>{@code E}
753      * <dt><i>SignedInteger:</i>
754      * <dd><i>Sign!(sub)opt</sub> Digits</i>
755      * <dt><i>Digits:</i>
756      * <dd><i>Digit</i>
757      * <dd><i>Digits Digit</i>
758      * <dt><i>Digit:</i>
759      * <dd>any character for which {@link Character#isDigit}
760      * returns {@code true}, including 0, 1, 2 ...
761      * </dl>
762      * </blockquote>
763      *
764      * <p>The scale of the returned {@code BigDecimal} will be the
765      * number of digits in the fraction, or zero if the string
766      * contains no decimal point, subject to adjustment for any
767      * exponent; if the string contains an exponent, the exponent is
768      * subtracted from the scale.  The value of the resulting scale
769      * must lie between {@code Integer.MIN_VALUE} and
770      * {@code Integer.MAX_VALUE}, inclusive.
771      *
772      * <p>The character-to-digit mapping is provided by {@link
773      * java.lang.Character#digit} set to convert to radix 10.  The
774      * string may not contain any extraneous characters (whitespace,
775      * for example).
776      *
777      * <p><b>Examples:</b><br>
778      * The value of the returned {@code BigDecimal} is equal to
779      * <i>significand</i> &times; 10!(sup)&nbsp;<i>exponent</i></sup>.
780      * For each string on the left, the resulting representation
781      * [{@code BigInteger}, {@code scale}] is shown on the right.
782      * <pre>
783      * "0"            [0,0]
784      * "0.00"         [0,2]
785      * "123"          [123,0]
786      * "-123"         [-123,0]
787      * "1.23E3"       [123,-1]
788      * "1.23E+3"      [123,-1]
789      * "12.3E+7"      [123,-6]
790      * "12.0"         [120,1]
791      * "12.3"         [123,1]
792      * "0.00123"      [123,5]
793      * "-1.23E-12"    [-123,14]
794      * "1234.5E-4"    [12345,5]
795      * "0E+7"         [0,-7]
796      * "-0"           [0,0]
797      * </pre>
798      *
799      * @apiNote For values other than {@code float} and
800      * {@code double} NaN and &plusmn;Infinity, this constructor is
801      * compatible with the values returned by {@link Float#toString}
802      * and {@link Double#toString}.  This is generally the preferred
803      * way to convert a {@code float} or {@code double} into a
804      * BigDecimal, as it doesn't suffer from the unpredictability of
805      * the {@link #BigDecimal(double)} constructor.
806      *
807      * @param val string representation of {@code BigDecimal}.
808      *
809      * @throws NumberFormatException if {@code val} is not a valid
810      *         representation of a {@code BigDecimal}.
811      */
812     this(string val)
813     {
814         // this(val.toCharArray(), 0, val.length());
815     }
816 
817     //     /**
818     //      * Translates the string representation of a {@code BigDecimal}
819     //      * into a {@code BigDecimal}, accepting the same strings as the
820     //      * {@link #BigDecimal(string)} constructor, with rounding
821     //      * according to the context settings.
822     //      *
823     //      * @param  val string representation of a {@code BigDecimal}.
824     //      * @param  mc the context to use.
825     //      * @throws ArithmeticException if the result is inexact but the
826     //      *         rounding mode is {@code UNNECESSARY}.
827     //      * @throws NumberFormatException if {@code val} is not a valid
828     //      *         representation of a BigDecimal.
829     //      */
830     //     BigDecimal(string val, MathContext mc) {
831     //         this(val.toCharArray(), 0, val.length(), mc);
832     //     }
833 
834     //     /**
835     //      * Translates a {@code double} into a {@code BigDecimal} which
836     //      * is the exact decimal representation of the {@code double}'s
837     //      * binary floating-point value.  The scale of the returned
838     //      * {@code BigDecimal} is the smallest value such that
839     //      * <code>(10!(sup)scale</sup> &times; val)</code> is an integer.
840     //      * <p>
841     //      * <b>Notes:</b>
842     //      * <ol>
843     //      * <li>
844     //      * The results of this constructor can be somewhat unpredictable.
845     //      * One might assume that writing {@code new BigDecimal(0.1)} in
846     //      * Java creates a {@code BigDecimal} which is exactly equal to
847     //      * 0.1 (an unscaled value of 1, with a scale of 1), but it is
848     //      * actually equal to
849     //      * 0.1000000000000000055511151231257827021181583404541015625.
850     //      * This is because 0.1 cannot be represented exactly as a
851     //      * {@code double} (or, for that matter, as a binary fraction of
852     //      * any finite length).  Thus, the value that is being passed
853     //      * <em>in</em> to the constructor is not exactly equal to 0.1,
854     //      * appearances notwithstanding.
855     //      *
856     //      * <li>
857     //      * The {@code string} constructor, on the other hand, is
858     //      * perfectly predictable: writing {@code new BigDecimal("0.1")}
859     //      * creates a {@code BigDecimal} which is <em>exactly</em> equal to
860     //      * 0.1, as one would expect.  Therefore, it is generally
861     //      * recommended that the {@linkplain #BigDecimal(string)
862     //      * string constructor} be used in preference to this one.
863     //      *
864     //      * <li>
865     //      * When a {@code double} must be used as a source for a
866     //      * {@code BigDecimal}, note that this constructor provides an
867     //      * exact conversion; it does not give the same result as
868     //      * converting the {@code double} to a {@code string} using the
869     //      * {@link Double#toString(double)} method and then using the
870     //      * {@link #BigDecimal(string)} constructor.  To get that result,
871     //      * use the {@code static} {@link #valueOf(double)} method.
872     //      * </ol>
873     //      *
874     //      * @param val {@code double} value to be converted to
875     //      *        {@code BigDecimal}.
876     //      * @throws NumberFormatException if {@code val} is infinite or NaN.
877     //      */
878     this(double val)
879     {
880         // this(val,MathContext.UNLIMITED);
881     }
882 
883     //     /**
884     //      * Translates a {@code double} into a {@code BigDecimal}, with
885     //      * rounding according to the context settings.  The scale of the
886     //      * {@code BigDecimal} is the smallest value such that
887     //      * <code>(10!(sup)scale</sup> &times; val)</code> is an integer.
888     //      *
889     //      * <p>The results of this constructor can be somewhat unpredictable
890     //      * and its use is generally not recommended; see the notes under
891     //      * the {@link #BigDecimal(double)} constructor.
892     //      *
893     //      * @param  val {@code double} value to be converted to
894     //      *         {@code BigDecimal}.
895     //      * @param  mc the context to use.
896     //      * @throws ArithmeticException if the result is inexact but the
897     //      *         RoundingMode is UNNECESSARY.
898     //      * @throws NumberFormatException if {@code val} is infinite or NaN.
899     //      */
900     //     BigDecimal(double val, MathContext mc) {
901     //         if (Double.isInfinite(val) || Double.isNaN(val))
902     //             throw new NumberFormatException("Infinite or NaN");
903     //         // Translate the double into sign, exponent and significand, according
904     //         // to the formulae in JLS, Section 20.10.22.
905     //         long valBits = Double.doubleToLongBits(val);
906     //         int sign = ((valBits >> 63) == 0 ? 1 : -1);
907     //         int exponent = (int) ((valBits >> 52) & 0x7ffL);
908     //         long significand = (exponent == 0
909     //                 ? (valBits & ((1L << 52) - 1)) << 1
910     //                 : (valBits & ((1L << 52) - 1)) | (1L << 52));
911     //         exponent -= 1075;
912     //         // At this point, val == sign * significand * 2**exponent.
913 
914     //         /*
915     //          * Special case zero to supress nonterminating normalization and bogus
916     //          * scale calculation.
917     //          */
918     //         if (significand == 0) {
919     //             this.intVal = BigInteger.ZERO;
920     //             this.scale = 0;
921     //             this.intCompact = 0;
922     //             this.precision = 1;
923     //             return;
924     //         }
925     //         // Normalize
926     //         while ((significand & 1) == 0) { // i.e., significand is even
927     //             significand >>= 1;
928     //             exponent++;
929     //         }
930     //         int scl = 0;
931     //         // Calculate intVal and scale
932     //         BigInteger rb;
933     //         long compactVal = sign * significand;
934     //         if (exponent == 0) {
935     //             rb = (compactVal == INFLATED) ? INFLATED_BIGINT : null;
936     //         } else {
937     //             if (exponent < 0) {
938     //                 rb = BigInteger.valueOf(5).pow(-exponent).multiply(compactVal);
939     //                 scl = -exponent;
940     //             } else { //  (exponent > 0)
941     //                 rb = BigInteger.TWO.pow(exponent).multiply(compactVal);
942     //             }
943     //             compactVal = compactValFor(rb);
944     //         }
945     //         int prec = 0;
946     //         int mcp = mc.precision;
947     //         if (mcp > 0) { // do rounding
948     //             int mode = mc.roundingMode.oldMode;
949     //             int drop;
950     //             if (compactVal == INFLATED) {
951     //                 prec = bigDigitLength(rb);
952     //                 drop = prec - mcp;
953     //                 while (drop > 0) {
954     //                     scl = checkScaleNonZero((long) scl - drop);
955     //                     rb = divideAndRoundByTenPow(rb, drop, mode);
956     //                     compactVal = compactValFor(rb);
957     //                     if (compactVal != INFLATED) {
958     //                         break;
959     //                     }
960     //                     prec = bigDigitLength(rb);
961     //                     drop = prec - mcp;
962     //                 }
963     //             }
964     //             if (compactVal != INFLATED) {
965     //                 prec = longDigitLength(compactVal);
966     //                 drop = prec - mcp;
967     //                 while (drop > 0) {
968     //                     scl = checkScaleNonZero((long) scl - drop);
969     //                     compactVal = divideAndRound(compactVal, LONG_TEN_POWERS_TABLE[drop], mc.roundingMode.oldMode);
970     //                     prec = longDigitLength(compactVal);
971     //                     drop = prec - mcp;
972     //                 }
973     //                 rb = null;
974     //             }
975     //         }
976     //         this.intVal = rb;
977     //         this.intCompact = compactVal;
978     //         this.scale = scl;
979     //         this.precision = prec;
980     //     }
981 
982     //     /**
983     //      * Translates a {@code BigInteger} into a {@code BigDecimal}.
984     //      * The scale of the {@code BigDecimal} is zero.
985     //      *
986     //      * @param val {@code BigInteger} value to be converted to
987     //      *            {@code BigDecimal}.
988     //      */
989     this(BigInteger val)
990     {
991         _scale = 0;
992         intVal = val;
993         // intCompact = compactValFor(val);
994     }
995 
996     //     /**
997     //      * Translates a {@code BigInteger} into a {@code BigDecimal}
998     //      * rounding according to the context settings.  The scale of the
999     //      * {@code BigDecimal} is zero.
1000     //      *
1001     //      * @param val {@code BigInteger} value to be converted to
1002     //      *            {@code BigDecimal}.
1003     //      * @param  mc the context to use.
1004     //      * @throws ArithmeticException if the result is inexact but the
1005     //      *         rounding mode is {@code UNNECESSARY}.
1006     //      */
1007     //     BigDecimal(BigInteger val, MathContext mc) {
1008     //         this(val,0,mc);
1009     //     }
1010 
1011     //     /**
1012     //      * Translates a {@code BigInteger} unscaled value and an
1013     //      * {@code int} scale into a {@code BigDecimal}.  The value of
1014     //      * the {@code BigDecimal} is
1015     //      * <code>(unscaledVal &times; 10!(sup)-scale</sup>)</code>.
1016     //      *
1017     //      * @param unscaledVal unscaled value of the {@code BigDecimal}.
1018     //      * @param scale scale of the {@code BigDecimal}.
1019     //      */
1020     //     BigDecimal(BigInteger unscaledVal, int scale) {
1021     //         // Negative scales are now allowed
1022     //         this.intVal = unscaledVal;
1023     //         this.intCompact = compactValFor(unscaledVal);
1024     //         this.scale = scale;
1025     //     }
1026 
1027     //     /**
1028     //      * Translates a {@code BigInteger} unscaled value and an
1029     //      * {@code int} scale into a {@code BigDecimal}, with rounding
1030     //      * according to the context settings.  The value of the
1031     //      * {@code BigDecimal} is <code>(unscaledVal &times;
1032     //      * 10!(sup)-scale</sup>)</code>, rounded according to the
1033     //      * {@code precision} and rounding mode settings.
1034     //      *
1035     //      * @param  unscaledVal unscaled value of the {@code BigDecimal}.
1036     //      * @param  scale scale of the {@code BigDecimal}.
1037     //      * @param  mc the context to use.
1038     //      * @throws ArithmeticException if the result is inexact but the
1039     //      *         rounding mode is {@code UNNECESSARY}.
1040     //      */
1041     //     BigDecimal(BigInteger unscaledVal, int scale, MathContext mc) {
1042     //         long compactVal = compactValFor(unscaledVal);
1043     //         int mcp = mc.precision;
1044     //         int prec = 0;
1045     //         if (mcp > 0) { // do rounding
1046     //             int mode = mc.roundingMode.oldMode;
1047     //             if (compactVal == INFLATED) {
1048     //                 prec = bigDigitLength(unscaledVal);
1049     //                 int drop = prec - mcp;
1050     //                 while (drop > 0) {
1051     //                     scale = checkScaleNonZero((long) scale - drop);
1052     //                     unscaledVal = divideAndRoundByTenPow(unscaledVal, drop, mode);
1053     //                     compactVal = compactValFor(unscaledVal);
1054     //                     if (compactVal != INFLATED) {
1055     //                         break;
1056     //                     }
1057     //                     prec = bigDigitLength(unscaledVal);
1058     //                     drop = prec - mcp;
1059     //                 }
1060     //             }
1061     //             if (compactVal != INFLATED) {
1062     //                 prec = longDigitLength(compactVal);
1063     //                 int drop = prec - mcp;     // drop can't be more than 18
1064     //                 while (drop > 0) {
1065     //                     scale = checkScaleNonZero((long) scale - drop);
1066     //                     compactVal = divideAndRound(compactVal, LONG_TEN_POWERS_TABLE[drop], mode);
1067     //                     prec = longDigitLength(compactVal);
1068     //                     drop = prec - mcp;
1069     //                 }
1070     //                 unscaledVal = null;
1071     //             }
1072     //         }
1073     //         this.intVal = unscaledVal;
1074     //         this.intCompact = compactVal;
1075     //         this.scale = scale;
1076     //         this.precision = prec;
1077     //     }
1078 
1079     /**
1080      * Translates an {@code int} into a {@code BigDecimal}.  The
1081      * scale of the {@code BigDecimal} is zero.
1082      *
1083      * @param val {@code int} value to be converted to
1084      *            {@code BigDecimal}.
1085      */
1086     this(int val)
1087     {
1088         this.intCompact = val;
1089         this._scale = 0;
1090         this.intVal = null;
1091     }
1092 
1093     //     /**
1094     //      * Translates an {@code int} into a {@code BigDecimal}, with
1095     //      * rounding according to the context settings.  The scale of the
1096     //      * {@code BigDecimal}, before any rounding, is zero.
1097     //      *
1098     //      * @param  val {@code int} value to be converted to {@code BigDecimal}.
1099     //      * @param  mc the context to use.
1100     //      * @throws ArithmeticException if the result is inexact but the
1101     //      *         rounding mode is {@code UNNECESSARY}.
1102     //      */
1103     //     BigDecimal(int val, MathContext mc) {
1104     //         int mcp = mc.precision;
1105     //         long compactVal = val;
1106     //         int scl = 0;
1107     //         int prec = 0;
1108     //         if (mcp > 0) { // do rounding
1109     //             prec = longDigitLength(compactVal);
1110     //             int drop = prec - mcp; // drop can't be more than 18
1111     //             while (drop > 0) {
1112     //                 scl = checkScaleNonZero((long) scl - drop);
1113     //                 compactVal = divideAndRound(compactVal, LONG_TEN_POWERS_TABLE[drop], mc.roundingMode.oldMode);
1114     //                 prec = longDigitLength(compactVal);
1115     //                 drop = prec - mcp;
1116     //             }
1117     //         }
1118     //         this.intVal = null;
1119     //         this.intCompact = compactVal;
1120     //         this.scale = scl;
1121     //         this.precision = prec;
1122     //     }
1123 
1124     /**
1125      * Translates a {@code long} into a {@code BigDecimal}.  The
1126      * scale of the {@code BigDecimal} is zero.
1127      *
1128      * @param val {@code long} value to be converted to {@code BigDecimal}.
1129      */
1130     this(long val)
1131     {
1132         this.intCompact = val;
1133         // this.intVal = (val == INFLATED) ? INFLATED_BIGINT : null;
1134         this._scale = 0;
1135     }
1136 
1137     //     /**
1138     //      * Translates a {@code long} into a {@code BigDecimal}, with
1139     //      * rounding according to the context settings.  The scale of the
1140     //      * {@code BigDecimal}, before any rounding, is zero.
1141     //      *
1142     //      * @param  val {@code long} value to be converted to {@code BigDecimal}.
1143     //      * @param  mc the context to use.
1144     //      * @throws ArithmeticException if the result is inexact but the
1145     //      *         rounding mode is {@code UNNECESSARY}.
1146     //      */
1147     //     BigDecimal(long val, MathContext mc) {
1148     //         int mcp = mc.precision;
1149     //         int mode = mc.roundingMode.oldMode;
1150     //         int prec = 0;
1151     //         int scl = 0;
1152     //         BigInteger rb = (val == INFLATED) ? INFLATED_BIGINT : null;
1153     //         if (mcp > 0) { // do rounding
1154     //             if (val == INFLATED) {
1155     //                 prec = 19;
1156     //                 int drop = prec - mcp;
1157     //                 while (drop > 0) {
1158     //                     scl = checkScaleNonZero((long) scl - drop);
1159     //                     rb = divideAndRoundByTenPow(rb, drop, mode);
1160     //                     val = compactValFor(rb);
1161     //                     if (val != INFLATED) {
1162     //                         break;
1163     //                     }
1164     //                     prec = bigDigitLength(rb);
1165     //                     drop = prec - mcp;
1166     //                 }
1167     //             }
1168     //             if (val != INFLATED) {
1169     //                 prec = longDigitLength(val);
1170     //                 int drop = prec - mcp;
1171     //                 while (drop > 0) {
1172     //                     scl = checkScaleNonZero((long) scl - drop);
1173     //                     val = divideAndRound(val, LONG_TEN_POWERS_TABLE[drop], mc.roundingMode.oldMode);
1174     //                     prec = longDigitLength(val);
1175     //                     drop = prec - mcp;
1176     //                 }
1177     //                 rb = null;
1178     //             }
1179     //         }
1180     //         this.intVal = rb;
1181     //         this.intCompact = val;
1182     //         this.scale = scl;
1183     //         this.precision = prec;
1184     //     }
1185 
1186     //     // Static Factory Methods
1187 
1188     //     /**
1189     //      * Translates a {@code long} unscaled value and an
1190     //      * {@code int} scale into a {@code BigDecimal}.
1191     //      *
1192     //      * @apiNote This static factory method is provided in preference
1193     //      * to a ({@code long}, {@code int}) constructor because it allows
1194     //      * for reuse of frequently used {@code BigDecimal} values.
1195     //      *
1196     //      * @param unscaledVal unscaled value of the {@code BigDecimal}.
1197     //      * @param scale scale of the {@code BigDecimal}.
1198     //      * @return a {@code BigDecimal} whose value is
1199     //      *         <code>(unscaledVal &times; 10!(sup)-scale</sup>)</code>.
1200     //      */
1201     static BigDecimal valueOf(long unscaledVal, int scale)
1202     {
1203         // if (scale == 0)
1204         //     return valueOf(unscaledVal);
1205         // else if (unscaledVal == 0) {
1206         //     return zeroValueOf(scale);
1207         // }
1208         // return new BigDecimal(unscaledVal == INFLATED ?
1209         //                       INFLATED_BIGINT : null,
1210         //                       unscaledVal, scale, 0);
1211         return null;
1212     }
1213 
1214     /**
1215      * Translates a {@code long} value into a {@code BigDecimal}
1216      * with a scale of zero.
1217      *
1218      * @apiNote This static factory method is provided in preference
1219      * to a ({@code long}) constructor because it allows for reuse of
1220      * frequently used {@code BigDecimal} values.
1221      *
1222      * @param val value of the {@code BigDecimal}.
1223      * @return a {@code BigDecimal} whose value is {@code val}.
1224      */
1225     static BigDecimal valueOf(long val)
1226     {
1227         // if (val >= 0 && val < ZERO_THROUGH_TEN.length)
1228         //     return ZERO_THROUGH_TEN[(int)val];
1229         // else if (val != INFLATED)
1230         //     return new BigDecimal(null, val, 0, 0);
1231         // return new BigDecimal(INFLATED_BIGINT, val, 0, 0);
1232         return null;
1233     }
1234 
1235     //     static BigDecimal valueOf(long unscaledVal, int scale, int prec) {
1236     //         if (scale == 0 && unscaledVal >= 0 && unscaledVal < ZERO_THROUGH_TEN.length) {
1237     //             return ZERO_THROUGH_TEN[(int) unscaledVal];
1238     //         } else if (unscaledVal == 0) {
1239     //             return zeroValueOf(scale);
1240     //         }
1241     //         return new BigDecimal(unscaledVal == INFLATED ? INFLATED_BIGINT : null,
1242     //                 unscaledVal, scale, prec);
1243     //     }
1244 
1245     //     static BigDecimal valueOf(BigInteger intVal, int scale, int prec) {
1246     //         long val = compactValFor(intVal);
1247     //         if (val == 0) {
1248     //             return zeroValueOf(scale);
1249     //         } else if (scale == 0 && val >= 0 && val < ZERO_THROUGH_TEN.length) {
1250     //             return ZERO_THROUGH_TEN[(int) val];
1251     //         }
1252     //         return new BigDecimal(intVal, val, scale, prec);
1253     //     }
1254 
1255     //     static BigDecimal zeroValueOf(int scale) {
1256     //         if (scale >= 0 && scale < ZERO_SCALED_BY.length)
1257     //             return ZERO_SCALED_BY[scale];
1258     //         else
1259     //             return new BigDecimal(BigInteger.ZERO, 0, scale, 1);
1260     //     }
1261 
1262     //     /**
1263     //      * Translates a {@code double} into a {@code BigDecimal}, using
1264     //      * the {@code double}'s canonical string representation provided
1265     //      * by the {@link Double#toString(double)} method.
1266     //      *
1267     //      * @apiNote This is generally the preferred way to convert a
1268     //      * {@code double} (or {@code float}) into a {@code BigDecimal}, as
1269     //      * the value returned is equal to that resulting from constructing
1270     //      * a {@code BigDecimal} from the result of using {@link
1271     //      * Double#toString(double)}.
1272     //      *
1273     //      * @param  val {@code double} to convert to a {@code BigDecimal}.
1274     //      * @return a {@code BigDecimal} whose value is equal to or approximately
1275     //      *         equal to the value of {@code val}.
1276     //      * @throws NumberFormatException if {@code val} is infinite or NaN.
1277     //      */
1278     //     static BigDecimal valueOf(double val) {
1279     //         // Reminder: a zero double returns '0.0', so we cannot fastpath
1280     //         // to use the constant ZERO.  This might be important enough to
1281     //         // justify a factory approach, a cache, or a few private
1282     //         // constants, later.
1283     //         return new BigDecimal(Double.toString(val));
1284     //     }
1285 
1286     //     // Arithmetic Operations
1287     //     /**
1288     //      * Returns a {@code BigDecimal} whose value is {@code (this +
1289     //      * augend)}, and whose scale is {@code max(this.scale(),
1290     //      * augend.scale())}.
1291     //      *
1292     //      * @param  augend value to be added to this {@code BigDecimal}.
1293     //      * @return {@code this + augend}
1294     //      */
1295     BigDecimal add(BigDecimal augend)
1296     {
1297         // if (this.intCompact != INFLATED) {
1298         //     if ((augend.intCompact != INFLATED)) {
1299         //         return add(this.intCompact, this.scale, augend.intCompact, augend.scale);
1300         //     } else {
1301         //         return add(this.intCompact, this.scale, augend.intVal, augend.scale);
1302         //     }
1303         // } else {
1304         //     if ((augend.intCompact != INFLATED)) {
1305         //         return add(augend.intCompact, augend.scale, this.intVal, this.scale);
1306         //     } else {
1307         //         return add(this.intVal, this.scale, augend.intVal, augend.scale);
1308         //     }
1309         // }
1310         return null;
1311     }
1312 
1313     //     /**
1314     //      * Returns a {@code BigDecimal} whose value is {@code (this + augend)},
1315     //      * with rounding according to the context settings.
1316     //      *
1317     //      * If either number is zero and the precision setting is nonzero then
1318     //      * the other number, rounded if necessary, is used as the result.
1319     //      *
1320     //      * @param  augend value to be added to this {@code BigDecimal}.
1321     //      * @param  mc the context to use.
1322     //      * @return {@code this + augend}, rounded as necessary.
1323     //      * @throws ArithmeticException if the result is inexact but the
1324     //      *         rounding mode is {@code UNNECESSARY}.
1325     //      */
1326     //     BigDecimal add(BigDecimal augend, MathContext mc) {
1327     //         if (mc.precision == 0)
1328     //             return add(augend);
1329     //         BigDecimal lhs = this;
1330 
1331     //         // If either number is zero then the other number, rounded and
1332     //         // scaled if necessary, is used as the result.
1333     //         {
1334     //             bool lhsIsZero = lhs.signum() == 0;
1335     //             bool augendIsZero = augend.signum() == 0;
1336 
1337     //             if (lhsIsZero || augendIsZero) {
1338     //                 int preferredScale = MathHelper.max(lhs.scale(), augend.scale());
1339     //                 BigDecimal result;
1340 
1341     //                 if (lhsIsZero && augendIsZero)
1342     //                     return zeroValueOf(preferredScale);
1343     //                 result = lhsIsZero ? doRound(augend, mc) : doRound(lhs, mc);
1344 
1345     //                 if (result.scale() == preferredScale)
1346     //                     return result;
1347     //                 else if (result.scale() > preferredScale) {
1348     //                     return stripZerosToMatchScale(result.intVal, result.intCompact, result.scale, preferredScale);
1349     //                 } else { // result.scale < preferredScale
1350     //                     int precisionDiff = mc.precision - result.precision();
1351     //                     int scaleDiff     = preferredScale - result.scale();
1352 
1353     //                     if (precisionDiff >= scaleDiff)
1354     //                         return result.setScale(preferredScale); // can achieve target scale
1355     //                     else
1356     //                         return result.setScale(result.scale() + precisionDiff);
1357     //                 }
1358     //             }
1359     //         }
1360 
1361     //         long padding = (long) lhs.scale - augend.scale;
1362     //         if (padding != 0) { // scales differ; alignment needed
1363     //             BigDecimal arg[] = preAlign(lhs, augend, padding, mc);
1364     //             matchScale(arg);
1365     //             lhs = arg[0];
1366     //             augend = arg[1];
1367     //         }
1368     //         return doRound(lhs.inflated().add(augend.inflated()), lhs.scale, mc);
1369     //     }
1370 
1371     //     /**
1372     //      * Returns an array of length two, the sum of whose entries is
1373     //      * equal to the rounded sum of the {@code BigDecimal} arguments.
1374     //      *
1375     //      * <p>If the digit positions of the arguments have a sufficient
1376     //      * gap between them, the value smaller in magnitude can be
1377     //      * condensed into a {@literal "sticky bit"} and the end result will
1378     //      * round the same way <em>if</em> the precision of the final
1379     //      * result does not include the high order digit of the small
1380     //      * magnitude operand.
1381     //      *
1382     //      * <p>Note that while strictly speaking this is an optimization,
1383     //      * it makes a much wider range of additions practical.
1384     //      *
1385     //      * <p>This corresponds to a pre-shift operation in a fixed
1386     //      * precision floating-point adder; this method is complicated by
1387     //      * variable precision of the result as determined by the
1388     //      * MathContext.  A more nuanced operation could implement a
1389     //      * {@literal "right shift"} on the smaller magnitude operand so
1390     //      * that the number of digits of the smaller operand could be
1391     //      * reduced even though the significands partially overlapped.
1392     //      */
1393     //     private BigDecimal[] preAlign(BigDecimal lhs, BigDecimal augend, long padding, MathContext mc) {
1394     //         assert padding != 0;
1395     //         BigDecimal big;
1396     //         BigDecimal small;
1397 
1398     //         if (padding < 0) { // lhs is big; augend is small
1399     //             big = lhs;
1400     //             small = augend;
1401     //         } else { // lhs is small; augend is big
1402     //             big = augend;
1403     //             small = lhs;
1404     //         }
1405 
1406     //         /*
1407     //          * This is the estimated scale of an ulp of the result; it assumes that
1408     //          * the result doesn't have a carry-out on a true add (e.g. 999 + 1 =>
1409     //          * 1000) or any subtractive cancellation on borrowing (e.g. 100 - 1.2 =>
1410     //          * 98.8)
1411     //          */
1412     //         long estResultUlpScale = (long) big.scale - big.precision() + mc.precision;
1413 
1414     //         /*
1415     //          * The low-order digit position of big is big.scale().  This
1416     //          * is true regardless of whether big has a positive or
1417     //          * negative scale.  The high-order digit position of small is
1418     //          * small.scale - (small.precision() - 1).  To do the full
1419     //          * condensation, the digit positions of big and small must be
1420     //          * disjoint *and* the digit positions of small should not be
1421     //          * directly visible in the result.
1422     //          */
1423     //         long smallHighDigitPos = (long) small.scale - small.precision() + 1;
1424     //         if (smallHighDigitPos > big.scale + 2 && // big and small disjoint
1425     //             smallHighDigitPos > estResultUlpScale + 2) { // small digits not visible
1426     //             small = BigDecimal.valueOf(small.signum(), this.checkScale(MathHelper.max(big.scale, estResultUlpScale) + 3));
1427     //         }
1428 
1429     //         // Since addition is symmetric, preserving input order in
1430     //         // returned operands doesn't matter
1431     //         BigDecimal[] result = {big, small};
1432     //         return result;
1433     //     }
1434 
1435     /**
1436      * Returns a {@code BigDecimal} whose value is {@code (this -
1437      * subtrahend)}, and whose scale is {@code max(this.scale(),
1438      * subtrahend.scale())}.
1439      *
1440      * @param  subtrahend value to be subtracted from this {@code BigDecimal}.
1441      * @return {@code this - subtrahend}
1442      */
1443     BigDecimal subtract(BigDecimal subtrahend)
1444     {
1445         // if (this.intCompact != INFLATED) {
1446         //     if ((subtrahend.intCompact != INFLATED)) {
1447         //         return add(this.intCompact, this.scale, -subtrahend.intCompact, subtrahend.scale);
1448         //     } else {
1449         //         return add(this.intCompact, this.scale, subtrahend.intVal.negate(), subtrahend.scale);
1450         //     }
1451         // } else {
1452         //     if ((subtrahend.intCompact != INFLATED)) {
1453         //         // Pair of subtrahend values given before pair of
1454         //         // values from this BigDecimal to avoid need for
1455         //         // method overloading on the specialized add method
1456         //         return add(-subtrahend.intCompact, subtrahend.scale, this.intVal, this.scale);
1457         //     } else {
1458         //         return add(this.intVal, this.scale, subtrahend.intVal.negate(), subtrahend.scale);
1459         //     }
1460         // }
1461         return null;
1462     }
1463 
1464     //     /**
1465     //      * Returns a {@code BigDecimal} whose value is {@code (this - subtrahend)},
1466     //      * with rounding according to the context settings.
1467     //      *
1468     //      * If {@code subtrahend} is zero then this, rounded if necessary, is used as the
1469     //      * result.  If this is zero then the result is {@code subtrahend.negate(mc)}.
1470     //      *
1471     //      * @param  subtrahend value to be subtracted from this {@code BigDecimal}.
1472     //      * @param  mc the context to use.
1473     //      * @return {@code this - subtrahend}, rounded as necessary.
1474     //      * @throws ArithmeticException if the result is inexact but the
1475     //      *         rounding mode is {@code UNNECESSARY}.
1476     //      */
1477     //     BigDecimal subtract(BigDecimal subtrahend, MathContext mc) {
1478     //         if (mc.precision == 0)
1479     //             return subtract(subtrahend);
1480     //         // share the special rounding code in add()
1481     //         return add(subtrahend.negate(), mc);
1482     //     }
1483 
1484     /**
1485      * Returns a {@code BigDecimal} whose value is <code>(this &times;
1486      * multiplicand)</code>, and whose scale is {@code (this.scale() +
1487      * multiplicand.scale())}.
1488      *
1489      * @param  multiplicand value to be multiplied by this {@code BigDecimal}.
1490      * @return {@code this * multiplicand}
1491      */
1492     BigDecimal multiply(BigDecimal multiplicand)
1493     {
1494         // int productScale = checkScale((long) scale + multiplicand.scale);
1495         // if (this.intCompact != INFLATED) {
1496         //     if ((multiplicand.intCompact != INFLATED)) {
1497         //         return multiply(this.intCompact, multiplicand.intCompact, productScale);
1498         //     } else {
1499         //         return multiply(this.intCompact, multiplicand.intVal, productScale);
1500         //     }
1501         // } else {
1502         //     if ((multiplicand.intCompact != INFLATED)) {
1503         //         return multiply(multiplicand.intCompact, this.intVal, productScale);
1504         //     } else {
1505         //         return multiply(this.intVal, multiplicand.intVal, productScale);
1506         //     }
1507         // }
1508         return null;
1509     }
1510 
1511     //     /**
1512     //      * Returns a {@code BigDecimal} whose value is <code>(this &times;
1513     //      * multiplicand)</code>, with rounding according to the context settings.
1514     //      *
1515     //      * @param  multiplicand value to be multiplied by this {@code BigDecimal}.
1516     //      * @param  mc the context to use.
1517     //      * @return {@code this * multiplicand}, rounded as necessary.
1518     //      * @throws ArithmeticException if the result is inexact but the
1519     //      *         rounding mode is {@code UNNECESSARY}.
1520     //      */
1521     //     BigDecimal multiply(BigDecimal multiplicand, MathContext mc) {
1522     //         if (mc.precision == 0)
1523     //             return multiply(multiplicand);
1524     //         int productScale = checkScale((long) scale + multiplicand.scale);
1525     //         if (this.intCompact != INFLATED) {
1526     //             if ((multiplicand.intCompact != INFLATED)) {
1527     //                 return multiplyAndRound(this.intCompact, multiplicand.intCompact, productScale, mc);
1528     //             } else {
1529     //                 return multiplyAndRound(this.intCompact, multiplicand.intVal, productScale, mc);
1530     //             }
1531     //         } else {
1532     //             if ((multiplicand.intCompact != INFLATED)) {
1533     //                 return multiplyAndRound(multiplicand.intCompact, this.intVal, productScale, mc);
1534     //             } else {
1535     //                 return multiplyAndRound(this.intVal, multiplicand.intVal, productScale, mc);
1536     //             }
1537     //         }
1538     //     }
1539 
1540     //     /**
1541     //      * Returns a {@code BigDecimal} whose value is {@code (this /
1542     //      * divisor)}, and whose scale is as specified.  If rounding must
1543     //      * be performed to generate a result with the specified scale, the
1544     //      * specified rounding mode is applied.
1545     //      *
1546     //      * @deprecated The method {@link #divide(BigDecimal, int, RoundingMode)}
1547     //      * should be used in preference to this legacy method.
1548     //      *
1549     //      * @param  divisor value by which this {@code BigDecimal} is to be divided.
1550     //      * @param  scale scale of the {@code BigDecimal} quotient to be returned.
1551     //      * @param  roundingMode rounding mode to apply.
1552     //      * @return {@code this / divisor}
1553     //      * @throws ArithmeticException if {@code divisor} is zero,
1554     //      *         {@code roundingMode==ROUND_UNNECESSARY} and
1555     //      *         the specified scale is insufficient to represent the result
1556     //      *         of the division exactly.
1557     //      * @throws IllegalArgumentException if {@code roundingMode} does not
1558     //      *         represent a valid rounding mode.
1559     //      * @see    #ROUND_UP
1560     //      * @see    #ROUND_DOWN
1561     //      * @see    #ROUND_CEILING
1562     //      * @see    #ROUND_FLOOR
1563     //      * @see    #ROUND_HALF_UP
1564     //      * @see    #ROUND_HALF_DOWN
1565     //      * @see    #ROUND_HALF_EVEN
1566     //      * @see    #ROUND_UNNECESSARY
1567     //      */
1568     //     //@Deprecated(since="9")
1569     //     BigDecimal divide(BigDecimal divisor, int scale, int roundingMode) {
1570     //         if (roundingMode < ROUND_UP || roundingMode > ROUND_UNNECESSARY)
1571     //             throw new IllegalArgumentException("Invalid rounding mode");
1572     //         if (this.intCompact != INFLATED) {
1573     //             if ((divisor.intCompact != INFLATED)) {
1574     //                 return divide(this.intCompact, this.scale, divisor.intCompact, divisor.scale, scale, roundingMode);
1575     //             } else {
1576     //                 return divide(this.intCompact, this.scale, divisor.intVal, divisor.scale, scale, roundingMode);
1577     //             }
1578     //         } else {
1579     //             if ((divisor.intCompact != INFLATED)) {
1580     //                 return divide(this.intVal, this.scale, divisor.intCompact, divisor.scale, scale, roundingMode);
1581     //             } else {
1582     //                 return divide(this.intVal, this.scale, divisor.intVal, divisor.scale, scale, roundingMode);
1583     //             }
1584     //         }
1585     //     }
1586 
1587     //     /**
1588     //      * Returns a {@code BigDecimal} whose value is {@code (this /
1589     //      * divisor)}, and whose scale is as specified.  If rounding must
1590     //      * be performed to generate a result with the specified scale, the
1591     //      * specified rounding mode is applied.
1592     //      *
1593     //      * @param  divisor value by which this {@code BigDecimal} is to be divided.
1594     //      * @param  scale scale of the {@code BigDecimal} quotient to be returned.
1595     //      * @param  roundingMode rounding mode to apply.
1596     //      * @return {@code this / divisor}
1597     //      * @throws ArithmeticException if {@code divisor} is zero,
1598     //      *         {@code roundingMode==RoundingMode.UNNECESSARY} and
1599     //      *         the specified scale is insufficient to represent the result
1600     //      *         of the division exactly.
1601     //      */
1602     //     BigDecimal divide(BigDecimal divisor, int scale, RoundingMode roundingMode) {
1603     //         return divide(divisor, scale, roundingMode.oldMode);
1604     //     }
1605 
1606     //     /**
1607     //      * Returns a {@code BigDecimal} whose value is {@code (this /
1608     //      * divisor)}, and whose scale is {@code this.scale()}.  If
1609     //      * rounding must be performed to generate a result with the given
1610     //      * scale, the specified rounding mode is applied.
1611     //      *
1612     //      * @deprecated The method {@link #divide(BigDecimal, RoundingMode)}
1613     //      * should be used in preference to this legacy method.
1614     //      *
1615     //      * @param  divisor value by which this {@code BigDecimal} is to be divided.
1616     //      * @param  roundingMode rounding mode to apply.
1617     //      * @return {@code this / divisor}
1618     //      * @throws ArithmeticException if {@code divisor==0}, or
1619     //      *         {@code roundingMode==ROUND_UNNECESSARY} and
1620     //      *         {@code this.scale()} is insufficient to represent the result
1621     //      *         of the division exactly.
1622     //      * @throws IllegalArgumentException if {@code roundingMode} does not
1623     //      *         represent a valid rounding mode.
1624     //      * @see    #ROUND_UP
1625     //      * @see    #ROUND_DOWN
1626     //      * @see    #ROUND_CEILING
1627     //      * @see    #ROUND_FLOOR
1628     //      * @see    #ROUND_HALF_UP
1629     //      * @see    #ROUND_HALF_DOWN
1630     //      * @see    #ROUND_HALF_EVEN
1631     //      * @see    #ROUND_UNNECESSARY
1632     //      */
1633     //     //@Deprecated(since="9")
1634     BigDecimal divide(BigDecimal divisor, int roundingMode)
1635     {
1636         // return this.divide(divisor, scale, roundingMode);
1637         return null;
1638     }
1639 
1640     //     /**
1641     //      * Returns a {@code BigDecimal} whose value is {@code (this /
1642     //      * divisor)}, and whose scale is {@code this.scale()}.  If
1643     //      * rounding must be performed to generate a result with the given
1644     //      * scale, the specified rounding mode is applied.
1645     //      *
1646     //      * @param  divisor value by which this {@code BigDecimal} is to be divided.
1647     //      * @param  roundingMode rounding mode to apply.
1648     //      * @return {@code this / divisor}
1649     //      * @throws ArithmeticException if {@code divisor==0}, or
1650     //      *         {@code roundingMode==RoundingMode.UNNECESSARY} and
1651     //      *         {@code this.scale()} is insufficient to represent the result
1652     //      *         of the division exactly.
1653     //      */
1654     //     BigDecimal divide(BigDecimal divisor, RoundingMode roundingMode) {
1655     //         return this.divide(divisor, scale, roundingMode.oldMode);
1656     //     }
1657 
1658     //     /**
1659     //      * Returns a {@code BigDecimal} whose value is {@code (this /
1660     //      * divisor)}, and whose preferred scale is {@code (this.scale() -
1661     //      * divisor.scale())}; if the exact quotient cannot be
1662     //      * represented (because it has a non-terminating decimal
1663     //      * expansion) an {@code ArithmeticException} is thrown.
1664     //      *
1665     //      * @param  divisor value by which this {@code BigDecimal} is to be divided.
1666     //      * @throws ArithmeticException if the exact quotient does not have a
1667     //      *         terminating decimal expansion
1668     //      * @return {@code this / divisor}
1669     //      * @author Joseph D. Darcy
1670     //      */
1671     BigDecimal divide(BigDecimal divisor)
1672     {
1673         /*
1674          * Handle zero cases first.
1675          */
1676         // if (divisor.signum() == 0) {   // x/0
1677         //     if (this.signum() == 0)    // 0/0
1678         //         throw new ArithmeticException("Division undefined");  // NaN
1679         //     throw new ArithmeticException("Division by zero");
1680         // }
1681 
1682         // // Calculate preferred scale
1683         // int preferredScale = saturateLong((long) this.scale - divisor.scale);
1684 
1685         // if (this.signum() == 0) // 0/y
1686         //     return zeroValueOf(preferredScale);
1687         // else {
1688         //     /*
1689         //      * If the quotient this/divisor has a terminating decimal
1690         //      * expansion, the expansion can have no more than
1691         //      * (a.precision() + ceil(10*b.precision)/3) digits.
1692         //      * Therefore, create a MathContext object with this
1693         //      * precision and do a divide with the UNNECESSARY rounding
1694         //      * mode.
1695         //      */
1696         //     MathContext mc = new MathContext( (int)MathHelper.min(this.precision() +
1697         //                                                     (long)MathHelper.ceil(10.0*divisor.precision()/3.0),
1698         //                                                     Integer.MAX_VALUE),
1699         //                                       RoundingMode.UNNECESSARY);
1700         //     BigDecimal quotient;
1701         //     try {
1702         //         quotient = this.divide(divisor, mc);
1703         //     } catch (ArithmeticException e) {
1704         //         throw new ArithmeticException("Non-terminating decimal expansion; " ~
1705         //                                       "no exact representable decimal result.");
1706         //     }
1707 
1708         //     int quotientScale = quotient.scale();
1709 
1710         //     // divide(BigDecimal, mc) tries to adjust the quotient to
1711         //     // the desired one by removing trailing zeros; since the
1712         //     // exact divide method does not have an explicit digit
1713         //     // limit, we can add zeros too.
1714         //     if (preferredScale > quotientScale)
1715         //         return quotient.setScale(preferredScale, ROUND_UNNECESSARY);
1716 
1717         //     return quotient;
1718         // }
1719         return null;
1720     }
1721 
1722     //     /**
1723     //      * Returns a {@code BigDecimal} whose value is {@code (this /
1724     //      * divisor)}, with rounding according to the context settings.
1725     //      *
1726     //      * @param  divisor value by which this {@code BigDecimal} is to be divided.
1727     //      * @param  mc the context to use.
1728     //      * @return {@code this / divisor}, rounded as necessary.
1729     //      * @throws ArithmeticException if the result is inexact but the
1730     //      *         rounding mode is {@code UNNECESSARY} or
1731     //      *         {@code mc.precision == 0} and the quotient has a
1732     //      *         non-terminating decimal expansion.
1733     //      */
1734     //     BigDecimal divide(BigDecimal divisor, MathContext mc) {
1735     //         int mcp = mc.precision;
1736     //         if (mcp == 0)
1737     //             return divide(divisor);
1738 
1739     //         BigDecimal dividend = this;
1740     //         long preferredScale = (long)dividend.scale - divisor.scale;
1741     //         // Now calculate the answer.  We use the existing
1742     //         // divide-and-round method, but as this rounds to scale we have
1743     //         // to normalize the values here to achieve the desired result.
1744     //         // For x/y we first handle y=0 and x=0, and then normalize x and
1745     //         // y to give x' and y' with the following constraints:
1746     //         //   (a) 0.1 <= x' < 1
1747     //         //   (b)  x' <= y' < 10*x'
1748     //         // Dividing x'/y' with the required scale set to mc.precision then
1749     //         // will give a result in the range 0.1 to 1 rounded to exactly
1750     //         // the right number of digits (except in the case of a result of
1751     //         // 1.000... which can arise when x=y, or when rounding overflows
1752     //         // The 1.000... case will reduce properly to 1.
1753     //         if (divisor.signum() == 0) {      // x/0
1754     //             if (dividend.signum() == 0)    // 0/0
1755     //                 throw new ArithmeticException("Division undefined");  // NaN
1756     //             throw new ArithmeticException("Division by zero");
1757     //         }
1758     //         if (dividend.signum() == 0) // 0/y
1759     //             return zeroValueOf(saturateLong(preferredScale));
1760     //         int xscale = dividend.precision();
1761     //         int yscale = divisor.precision();
1762     //         if(dividend.intCompact!=INFLATED) {
1763     //             if(divisor.intCompact!=INFLATED) {
1764     //                 return divide(dividend.intCompact, xscale, divisor.intCompact, yscale, preferredScale, mc);
1765     //             } else {
1766     //                 return divide(dividend.intCompact, xscale, divisor.intVal, yscale, preferredScale, mc);
1767     //             }
1768     //         } else {
1769     //             if(divisor.intCompact!=INFLATED) {
1770     //                 return divide(dividend.intVal, xscale, divisor.intCompact, yscale, preferredScale, mc);
1771     //             } else {
1772     //                 return divide(dividend.intVal, xscale, divisor.intVal, yscale, preferredScale, mc);
1773     //             }
1774     //         }
1775     //     }
1776 
1777     //     /**
1778     //      * Returns a {@code BigDecimal} whose value is the integer part
1779     //      * of the quotient {@code (this / divisor)} rounded down.  The
1780     //      * preferred scale of the result is {@code (this.scale() -
1781     //      * divisor.scale())}.
1782     //      *
1783     //      * @param  divisor value by which this {@code BigDecimal} is to be divided.
1784     //      * @return The integer part of {@code this / divisor}.
1785     //      * @throws ArithmeticException if {@code divisor==0}
1786     //      */
1787     BigDecimal divideToIntegralValue(BigDecimal divisor)
1788     {
1789         // Calculate preferred scale
1790         // int preferredScale = saturateLong((long) this.scale - divisor.scale);
1791         // if (this.compareMagnitude(divisor) < 0) {
1792         //     // much faster when this << divisor
1793         //     return zeroValueOf(preferredScale);
1794         // }
1795 
1796         // if (this.signum() == 0 && divisor.signum() != 0)
1797         //     return this.setScale(preferredScale, ROUND_UNNECESSARY);
1798 
1799         // // Perform a divide with enough digits to round to a correct
1800         // // integer value; then remove any fractional digits
1801         // import std.algorithm.comparison;
1802         // import std.math;
1803         // int maxDigits = cast(int)MathHelper.min(this.precision() +
1804         //                               cast(long)MathHelper.ceil(10.0*divisor.precision()/3.0) +
1805         //                               abs(cast(long)this.scale() - divisor.scale()) + 2,
1806         //                               Integer.MAX_VALUE);
1807         // BigDecimal quotient = this.divide(divisor, new MathContext(maxDigits,
1808         //                                                            RoundingMode.DOWN));
1809         // if (quotient.scale > 0) {
1810         //     quotient = quotient.setScale(0, RoundingMode.DOWN);
1811         //     quotient = stripZerosToMatchScale(quotient.intVal, quotient.intCompact, quotient.scale, preferredScale);
1812         // }
1813 
1814         // if (quotient.scale < preferredScale) {
1815         //     // pad with zeros if necessary
1816         //     quotient = quotient.setScale(preferredScale, ROUND_UNNECESSARY);
1817         // }
1818 
1819         // return quotient;
1820         return null;
1821     }
1822 
1823     //     /**
1824     //      * Returns a {@code BigDecimal} whose value is the integer part
1825     //      * of {@code (this / divisor)}.  Since the integer part of the
1826     //      * exact quotient does not depend on the rounding mode, the
1827     //      * rounding mode does not affect the values returned by this
1828     //      * method.  The preferred scale of the result is
1829     //      * {@code (this.scale() - divisor.scale())}.  An
1830     //      * {@code ArithmeticException} is thrown if the integer part of
1831     //      * the exact quotient needs more than {@code mc.precision}
1832     //      * digits.
1833     //      *
1834     //      * @param  divisor value by which this {@code BigDecimal} is to be divided.
1835     //      * @param  mc the context to use.
1836     //      * @return The integer part of {@code this / divisor}.
1837     //      * @throws ArithmeticException if {@code divisor==0}
1838     //      * @throws ArithmeticException if {@code mc.precision} {@literal >} 0 and the result
1839     //      *         requires a precision of more than {@code mc.precision} digits.
1840     //      * @author Joseph D. Darcy
1841     //      */
1842     //     BigDecimal divideToIntegralValue(BigDecimal divisor, MathContext mc) {
1843     //         if (mc.precision == 0 || // exact result
1844     //             (this.compareMagnitude(divisor) < 0)) // zero result
1845     //             return divideToIntegralValue(divisor);
1846 
1847     //         // Calculate preferred scale
1848     //         int preferredScale = saturateLong((long)this.scale - divisor.scale);
1849 
1850     //         /*
1851     //          * Perform a normal divide to mc.precision digits.  If the
1852     //          * remainder has absolute value less than the divisor, the
1853     //          * integer portion of the quotient fits into mc.precision
1854     //          * digits.  Next, remove any fractional digits from the
1855     //          * quotient and adjust the scale to the preferred value.
1856     //          */
1857     //         BigDecimal result = this.divide(divisor, new MathContext(mc.precision, RoundingMode.DOWN));
1858 
1859     //         if (result.scale() < 0) {
1860     //             /*
1861     //              * Result is an integer. See if quotient represents the
1862     //              * full integer portion of the exact quotient; if it does,
1863     //              * the computed remainder will be less than the divisor.
1864     //              */
1865     //             BigDecimal product = result.multiply(divisor);
1866     //             // If the quotient is the full integer value,
1867     //             // |dividend-product| < |divisor|.
1868     //             if (this.subtract(product).compareMagnitude(divisor) >= 0) {
1869     //                 throw new ArithmeticException("Division impossible");
1870     //             }
1871     //         } else if (result.scale() > 0) {
1872     //             /*
1873     //              * Integer portion of quotient will fit into precision
1874     //              * digits; recompute quotient to scale 0 to avoid double
1875     //              * rounding and then try to adjust, if necessary.
1876     //              */
1877     //             result = result.setScale(0, RoundingMode.DOWN);
1878     //         }
1879     //         // else result.scale() == 0;
1880 
1881     //         int precisionDiff;
1882     //         if ((preferredScale > result.scale()) &&
1883     //             (precisionDiff = mc.precision - result.precision()) > 0) {
1884     //             return result.setScale(result.scale() +
1885     //                                    MathHelper.min(precisionDiff, preferredScale - result.scale) );
1886     //         } else {
1887     //             return stripZerosToMatchScale(result.intVal,result.intCompact,result.scale,preferredScale);
1888     //         }
1889     //     }
1890 
1891     //     /**
1892     //      * Returns a {@code BigDecimal} whose value is {@code (this % divisor)}.
1893     //      *
1894     //      * <p>The remainder is given by
1895     //      * {@code this.subtract(this.divideToIntegralValue(divisor).multiply(divisor))}.
1896     //      * Note that this is <em>not</em> the modulo operation (the result can be
1897     //      * negative).
1898     //      *
1899     //      * @param  divisor value by which this {@code BigDecimal} is to be divided.
1900     //      * @return {@code this % divisor}.
1901     //      * @throws ArithmeticException if {@code divisor==0}
1902     //      */
1903     //     BigDecimal remainder(BigDecimal divisor) {
1904     //         BigDecimal divrem[] = this.divideAndRemainder(divisor);
1905     //         return divrem[1];
1906     //     }
1907 
1908     //     /**
1909     //      * Returns a {@code BigDecimal} whose value is {@code (this %
1910     //      * divisor)}, with rounding according to the context settings.
1911     //      * The {@code MathContext} settings affect the implicit divide
1912     //      * used to compute the remainder.  The remainder computation
1913     //      * itself is by definition exact.  Therefore, the remainder may
1914     //      * contain more than {@code mc.getPrecision()} digits.
1915     //      *
1916     //      * <p>The remainder is given by
1917     //      * {@code this.subtract(this.divideToIntegralValue(divisor,
1918     //      * mc).multiply(divisor))}.  Note that this is not the modulo
1919     //      * operation (the result can be negative).
1920     //      *
1921     //      * @param  divisor value by which this {@code BigDecimal} is to be divided.
1922     //      * @param  mc the context to use.
1923     //      * @return {@code this % divisor}, rounded as necessary.
1924     //      * @throws ArithmeticException if {@code divisor==0}
1925     //      * @throws ArithmeticException if the result is inexact but the
1926     //      *         rounding mode is {@code UNNECESSARY}, or {@code mc.precision}
1927     //      *         {@literal >} 0 and the result of {@code this.divideToIntgralValue(divisor)} would
1928     //      *         require a precision of more than {@code mc.precision} digits.
1929     //      * @see    #divideToIntegralValue(java.math.BigDecimal, java.math.MathContext)
1930     //      */
1931     //     BigDecimal remainder(BigDecimal divisor, MathContext mc) {
1932     //         BigDecimal divrem[] = this.divideAndRemainder(divisor, mc);
1933     //         return divrem[1];
1934     //     }
1935 
1936     //     /**
1937     //      * Returns a two-element {@code BigDecimal} array containing the
1938     //      * result of {@code divideToIntegralValue} followed by the result of
1939     //      * {@code remainder} on the two operands.
1940     //      *
1941     //      * <p>Note that if both the integer quotient and remainder are
1942     //      * needed, this method is faster than using the
1943     //      * {@code divideToIntegralValue} and {@code remainder} methods
1944     //      * separately because the division need only be carried out once.
1945     //      *
1946     //      * @param  divisor value by which this {@code BigDecimal} is to be divided,
1947     //      *         and the remainder computed.
1948     //      * @return a two element {@code BigDecimal} array: the quotient
1949     //      *         (the result of {@code divideToIntegralValue}) is the initial element
1950     //      *         and the remainder is the final element.
1951     //      * @throws ArithmeticException if {@code divisor==0}
1952     //      * @see    #divideToIntegralValue(java.math.BigDecimal, java.math.MathContext)
1953     //      * @see    #remainder(java.math.BigDecimal, java.math.MathContext)
1954     //      */
1955     //     BigDecimal[] divideAndRemainder(BigDecimal divisor) {
1956     //         // we use the identity  x = i * y + r to determine r
1957     //         BigDecimal[] result = new BigDecimal[2];
1958 
1959     //         result[0] = this.divideToIntegralValue(divisor);
1960     //         result[1] = this.subtract(result[0].multiply(divisor));
1961     //         return result;
1962     //     }
1963 
1964     //     /**
1965     //      * Returns a two-element {@code BigDecimal} array containing the
1966     //      * result of {@code divideToIntegralValue} followed by the result of
1967     //      * {@code remainder} on the two operands calculated with rounding
1968     //      * according to the context settings.
1969     //      *
1970     //      * <p>Note that if both the integer quotient and remainder are
1971     //      * needed, this method is faster than using the
1972     //      * {@code divideToIntegralValue} and {@code remainder} methods
1973     //      * separately because the division need only be carried out once.
1974     //      *
1975     //      * @param  divisor value by which this {@code BigDecimal} is to be divided,
1976     //      *         and the remainder computed.
1977     //      * @param  mc the context to use.
1978     //      * @return a two element {@code BigDecimal} array: the quotient
1979     //      *         (the result of {@code divideToIntegralValue}) is the
1980     //      *         initial element and the remainder is the final element.
1981     //      * @throws ArithmeticException if {@code divisor==0}
1982     //      * @throws ArithmeticException if the result is inexact but the
1983     //      *         rounding mode is {@code UNNECESSARY}, or {@code mc.precision}
1984     //      *         {@literal >} 0 and the result of {@code this.divideToIntgralValue(divisor)} would
1985     //      *         require a precision of more than {@code mc.precision} digits.
1986     //      * @see    #divideToIntegralValue(java.math.BigDecimal, java.math.MathContext)
1987     //      * @see    #remainder(java.math.BigDecimal, java.math.MathContext)
1988     //      */
1989     //     BigDecimal[] divideAndRemainder(BigDecimal divisor, MathContext mc) {
1990     //         if (mc.precision == 0)
1991     //             return divideAndRemainder(divisor);
1992 
1993     //         BigDecimal[] result = new BigDecimal[2];
1994     //         BigDecimal lhs = this;
1995 
1996     //         result[0] = lhs.divideToIntegralValue(divisor, mc);
1997     //         result[1] = lhs.subtract(result[0].multiply(divisor));
1998     //         return result;
1999     //     }
2000 
2001     //     /**
2002     //      * Returns an approximation to the square root of {@code this}
2003     //      * with rounding according to the context settings.
2004     //      *
2005     //      * <p>The preferred scale of the returned result is equal to
2006     //      * {@code this.scale()/2}. The value of the returned result is
2007     //      * always within one ulp of the exact decimal value for the
2008     //      * precision in question.  If the rounding mode is {@link
2009     //      * RoundingMode#HALF_UP HALF_UP}, {@link RoundingMode#HALF_DOWN
2010     //      * HALF_DOWN}, or {@link RoundingMode#HALF_EVEN HALF_EVEN}, the
2011     //      * result is within one half an ulp of the exact decimal value.
2012     //      *
2013     //      * <p>Special case:
2014     //      * <ul>
2015     //      * <li> The square root of a number numerically equal to {@code
2016     //      * ZERO} is numerically equal to {@code ZERO} with a preferred
2017     //      * scale according to the general rule above. In particular, for
2018     //      * {@code ZERO}, {@code ZERO.sqrt(mc).equals(ZERO)} is true with
2019     //      * any {@code MathContext} as an argument.
2020     //      * </ul>
2021     //      *
2022     //      * @param mc the context to use.
2023     //      * @return the square root of {@code this}.
2024     //      * @throws ArithmeticException if {@code this} is less than zero.
2025     //      * @throws ArithmeticException if an exact result is requested
2026     //      * ({@code mc.getPrecision()==0}) and there is no finite decimal
2027     //      * expansion of the exact result
2028     //      * @throws ArithmeticException if
2029     //      * {@code (mc.getRoundingMode()==RoundingMode.UNNECESSARY}) and
2030     //      * the exact result cannot fit in {@code mc.getPrecision()}
2031     //      * digits.
2032     //      * @see BigInteger#sqrt()
2033     //      */
2034     //     BigDecimal sqrt(MathContext mc) {
2035     //         int signum = signum();
2036     //         if (signum == 1) {
2037     //             /*
2038     //              * The following code draws on the algorithm presented in
2039     //              * "Properly Rounded Variable Precision Square Root," Hull and
2040     //              * Abrham, ACM Transactions on Mathematical Software, Vol 11,
2041     //              * No. 3, September 1985, Pages 229-237.
2042     //              *
2043     //              * The BigDecimal computational model differs from the one
2044     //              * presented in the paper in several ways: first BigDecimal
2045     //              * numbers aren't necessarily normalized, second many more
2046     //              * rounding modes are supported, including UNNECESSARY, and
2047     //              * exact results can be requested.
2048     //              *
2049     //              * The main steps of the algorithm below are as follows,
2050     //              * first argument reduce the value to the numerical range
2051     //              * [1, 10) using the following relations:
2052     //              *
2053     //              * x = y * 10 ^ exp
2054     //              * sqrt(x) = sqrt(y) * 10^(exp / 2) if exp is even
2055     //              * sqrt(x) = sqrt(y/10) * 10 ^((exp+1)/2) is exp is odd
2056     //              *
2057     //              * Then use Newton's iteration on the reduced value to compute
2058     //              * the numerical digits of the desired result.
2059     //              *
2060     //              * Finally, scale back to the desired exponent range and
2061     //              * perform any adjustment to get the preferred scale in the
2062     //              * representation.
2063     //              */
2064 
2065     //             // The code below favors relative simplicity over checking
2066     //             // for special cases that could run faster.
2067 
2068     //             int preferredScale = this.scale()/2;
2069     //             BigDecimal zeroWithFinalPreferredScale = valueOf(0L, preferredScale);
2070 
2071     //             // First phase of numerical normalization, strip trailing
2072     //             // zeros and check for even powers of 10.
2073     //             BigDecimal stripped = this.stripTrailingZeros();
2074     //             int strippedScale = stripped.scale();
2075 
2076     //             // Numerically sqrt(10^2N) = 10^N
2077     //             if (stripped.isPowerOfTen() &&
2078     //                 strippedScale % 2 == 0) {
2079     //                 BigDecimal result = valueOf(1L, strippedScale/2);
2080     //                 if (result.scale() != preferredScale) {
2081     //                     // Adjust to requested precision and preferred
2082     //                     // scale as appropriate.
2083     //                     result = result.add(zeroWithFinalPreferredScale, mc);
2084     //                 }
2085     //                 return result;
2086     //             }
2087 
2088     //             // After stripTrailingZeros, the representation is normalized as
2089     //             //
2090     //             // unscaledValue * 10^(-scale)
2091     //             //
2092     //             // where unscaledValue is an integer with the mimimum
2093     //             // precision for the cohort of the numerical value. To
2094     //             // allow binary floating-point hardware to be used to get
2095     //             // approximately a 15 digit approximation to the square
2096     //             // root, it is helpful to instead normalize this so that
2097     //             // the significand portion is to right of the decimal
2098     //             // point by roughly (scale() - precision() +1).
2099 
2100     //             // Now the precision / scale adjustment
2101     //             int scaleAdjust = 0;
2102     //             int scale = stripped.scale() - stripped.precision() + 1;
2103     //             if (scale % 2 == 0) {
2104     //                 scaleAdjust = scale;
2105     //             } else {
2106     //                 scaleAdjust = scale - 1;
2107     //             }
2108 
2109     //             BigDecimal working = stripped.scaleByPowerOfTen(scaleAdjust);
2110 
2111     //             assert  // Verify 0.1 <= working < 10
2112     //                 ONE_TENTH.compareTo(working) <= 0 && working.compareTo(TEN) < 0;
2113 
2114     //             // Use good ole' MathHelper.sqrt to get the initial guess for
2115     //             // the Newton iteration, good to at least 15 decimal
2116     //             // digits. This approach does incur the cost of a
2117     //             //
2118     //             // BigDecimal -> double -> BigDecimal
2119     //             //
2120     //             // conversion cycle, but it avoids the need for several
2121     //             // Newton iterations in BigDecimal arithmetic to get the
2122     //             // working answer to 15 digits of precision. If many fewer
2123     //             // than 15 digits were needed, it might be faster to do
2124     //             // the loop entirely in BigDecimal arithmetic.
2125     //             //
2126     //             // (A double value might have as much many as 17 decimal
2127     //             // digits of precision; it depends on the relative density
2128     //             // of binary and decimal numbers at different regions of
2129     //             // the number line.)
2130     //             //
2131     //             // (It would be possible to check for certain special
2132     //             // cases to avoid doing any Newton iterations. For
2133     //             // example, if the BigDecimal -> double conversion was
2134     //             // known to be exact and the rounding mode had a
2135     //             // low-enough precision, the post-Newton rounding logic
2136     //             // could be applied directly.)
2137 
2138     //             BigDecimal guess = new BigDecimal(MathHelper.sqrt(working.doubleValue()));
2139     //             int guessPrecision = 15;
2140     //             int originalPrecision = mc.getPrecision();
2141     //             int targetPrecision;
2142 
2143     //             // If an exact value is requested, it must only need about
2144     //             // half of the input digits to represent since multiplying
2145     //             // an N digit number by itself yield a 2N-1 digit or 2N
2146     //             // digit result.
2147     //             if (originalPrecision == 0) {
2148     //                 targetPrecision = stripped.precision()/2 + 1;
2149     //             } else {
2150     //                 targetPrecision = originalPrecision;
2151     //             }
2152 
2153     //             // When setting the precision to use inside the Newton
2154     //             // iteration loop, take care to avoid the case where the
2155     //             // precision of the input exceeds the requested precision
2156     //             // and rounding the input value too soon.
2157     //             BigDecimal approx = guess;
2158     //             int workingPrecision = working.precision();
2159     //             do {
2160     //                 int tmpPrecision = MathHelper.max(MathHelper.max(guessPrecision, targetPrecision + 2),
2161     //                                            workingPrecision);
2162     //                 MathContext mcTmp = new MathContext(tmpPrecision, RoundingMode.HALF_EVEN);
2163     //                 // approx = 0.5 * (approx + fraction / approx)
2164     //                 approx = ONE_HALF.multiply(approx.add(working.divide(approx, mcTmp), mcTmp));
2165     //                 guessPrecision *= 2;
2166     //             } while (guessPrecision < targetPrecision + 2);
2167 
2168     //             BigDecimal result;
2169     //             RoundingMode targetRm = mc.getRoundingMode();
2170     //             if (targetRm == RoundingMode.UNNECESSARY || originalPrecision == 0) {
2171     //                 RoundingMode tmpRm =
2172     //                     (targetRm == RoundingMode.UNNECESSARY) ? RoundingMode.DOWN : targetRm;
2173     //                 MathContext mcTmp = new MathContext(targetPrecision, tmpRm);
2174     //                 result = approx.scaleByPowerOfTen(-scaleAdjust/2).round(mcTmp);
2175 
2176     //                 // If result*result != this numerically, the square
2177     //                 // root isn't exact
2178     //                 if (this.subtract(result.multiply(result)).compareTo(ZERO) != 0) {
2179     //                     throw new ArithmeticException("Computed square root not exact.");
2180     //                 }
2181     //             } else {
2182     //                 result = approx.scaleByPowerOfTen(-scaleAdjust/2).round(mc);
2183     //             }
2184 
2185     //             if (result.scale() != preferredScale) {
2186     //                 // The preferred scale of an add is
2187     //                 // max(addend.scale(), augend.scale()). Therefore, if
2188     //                 // the scale of the result is first minimized using
2189     //                 // stripTrailingZeros(), adding a zero of the
2190     //                 // preferred scale rounding the correct precision will
2191     //                 // perform the proper scale vs precision tradeoffs.
2192     //                 result = result.stripTrailingZeros().
2193     //                     add(zeroWithFinalPreferredScale,
2194     //                         new MathContext(originalPrecision, RoundingMode.UNNECESSARY));
2195     //             }
2196     //             assert squareRootResultAssertions(result, mc);
2197     //             return result;
2198     //         } else {
2199     //             switch (signum) {
2200     //             case -1:
2201     //                 throw new ArithmeticException("Attempted square root " ~
2202     //                                               "of negative BigDecimal");
2203     //             case 0:
2204     //                 return valueOf(0L, scale()/2);
2205 
2206     //             default:
2207     //                 throw new AssertionError("Bad value from signum");
2208     //             }
2209     //         }
2210     //     }
2211 
2212     //     private bool isPowerOfTen() {
2213     //         return BigInteger.ONE.equals(this.unscaledValue());
2214     //     }
2215 
2216     //     /**
2217     //      * For nonzero values, check numerical correctness properties of
2218     //      * the computed result for the chosen rounding mode.
2219     //      *
2220     //      * For the directed roundings, for DOWN and FLOOR, result^2 must
2221     //      * be {@code <=} the input and (result+ulp)^2 must be {@code >} the
2222     //      * input. Conversely, for UP and CEIL, result^2 must be {@code >=} the
2223     //      * input and (result-ulp)^2 must be {@code <} the input.
2224     //      */
2225     //     private bool squareRootResultAssertions(BigDecimal result, MathContext mc) {
2226     //         if (result.signum() == 0) {
2227     //             return squareRootZeroResultAssertions(result, mc);
2228     //         } else {
2229     //             RoundingMode rm = mc.getRoundingMode();
2230     //             BigDecimal ulp = result.ulp();
2231     //             BigDecimal neighborUp   = result.add(ulp);
2232     //             // Make neighbor down accurate even for powers of ten
2233     //             if (this.isPowerOfTen()) {
2234     //                 ulp = ulp.divide(TEN);
2235     //             }
2236     //             BigDecimal neighborDown = result.subtract(ulp);
2237 
2238     //             // Both the starting value and result should be nonzero and positive.
2239     //             if (result.signum() != 1 ||
2240     //                 this.signum() != 1) {
2241     //                 return false;
2242     //             }
2243 
2244     //             switch (rm) {
2245     //             case DOWN:
2246     //             case FLOOR:
2247     //                 return
2248     //                     result.multiply(result).compareTo(this)         <= 0 &&
2249     //                     neighborUp.multiply(neighborUp).compareTo(this) > 0;
2250 
2251     //             case UP:
2252     //             case CEILING:
2253     //                 return
2254     //                     result.multiply(result).compareTo(this)             >= 0 &&
2255     //                     neighborDown.multiply(neighborDown).compareTo(this) < 0;
2256 
2257     //             case HALF_DOWN:
2258     //             case HALF_EVEN:
2259     //             case HALF_UP:
2260     //                 BigDecimal err = result.multiply(result).subtract(this).abs();
2261     //                 BigDecimal errUp = neighborUp.multiply(neighborUp).subtract(this);
2262     //                 BigDecimal errDown =  this.subtract(neighborDown.multiply(neighborDown));
2263     //                 // All error values should be positive so don't need to
2264     //                 // compare absolute values.
2265 
2266     //                 int err_comp_errUp = err.compareTo(errUp);
2267     //                 int err_comp_errDown = err.compareTo(errDown);
2268 
2269     //                 return
2270     //                     errUp.signum()   == 1 &&
2271     //                     errDown.signum() == 1 &&
2272 
2273     //                     err_comp_errUp   <= 0 &&
2274     //                     err_comp_errDown <= 0 &&
2275 
2276     //                     ((err_comp_errUp   == 0 ) ? err_comp_errDown < 0 : true) &&
2277     //                     ((err_comp_errDown == 0 ) ? err_comp_errUp   < 0 : true);
2278     //                 // && could check for digit conditions for ties too
2279 
2280     //             default: // Definition of UNNECESSARY already verified.
2281     //                 return true;
2282     //             }
2283     //         }
2284     //     }
2285 
2286     //     private bool squareRootZeroResultAssertions(BigDecimal result, MathContext mc) {
2287     //         return this.compareTo(ZERO) == 0;
2288     //     }
2289 
2290     //     /**
2291     //      * Returns a {@code BigDecimal} whose value is
2292     //      * <code>(this!(sup)n</sup>)</code>, The power is computed exactly, to
2293     //      * unlimited precision.
2294     //      *
2295     //      * <p>The parameter {@code n} must be in the range 0 through
2296     //      * 999999999, inclusive.  {@code ZERO.pow(0)} returns {@link
2297     //      * #ONE}.
2298     //      *
2299     //      * Note that future releases may expand the allowable exponent
2300     //      * range of this method.
2301     //      *
2302     //      * @param  n power to raise this {@code BigDecimal} to.
2303     //      * @return <code>this!(sup)n</sup></code>
2304     //      * @throws ArithmeticException if {@code n} is out of range.
2305     //      */
2306     //     BigDecimal pow(int n) {
2307     //         if (n < 0 || n > 999999999)
2308     //             throw new ArithmeticException("Invalid operation");
2309     //         // No need to calculate pow(n) if result will over/underflow.
2310     //         // Don't attempt to support "supernormal" numbers.
2311     //         int newScale = checkScale((long)scale * n);
2312     //         return new BigDecimal(this.inflated().pow(n), newScale);
2313     //     }
2314 
2315     //     /**
2316     //      * Returns a {@code BigDecimal} whose value is
2317     //      * <code>(this!(sup)n</sup>)</code>.  The current implementation uses
2318     //      * the core algorithm defined in ANSI standard X3.274-1996 with
2319     //      * rounding according to the context settings.  In general, the
2320     //      * returned numerical value is within two ulps of the exact
2321     //      * numerical value for the chosen precision.  Note that future
2322     //      * releases may use a different algorithm with a decreased
2323     //      * allowable error bound and increased allowable exponent range.
2324     //      *
2325     //      * <p>The X3.274-1996 algorithm is:
2326     //      *
2327     //      * <ul>
2328     //      * <li> An {@code ArithmeticException} exception is thrown if
2329     //      *  <ul>
2330     //      *    <li>{@code abs(n) > 999999999}
2331     //      *    <li>{@code mc.precision == 0} and {@code n < 0}
2332     //      *    <li>{@code mc.precision > 0} and {@code n} has more than
2333     //      *    {@code mc.precision} decimal digits
2334     //      *  </ul>
2335     //      *
2336     //      * <li> if {@code n} is zero, {@link #ONE} is returned even if
2337     //      * {@code this} is zero, otherwise
2338     //      * <ul>
2339     //      *   <li> if {@code n} is positive, the result is calculated via
2340     //      *   the repeated squaring technique into a single accumulator.
2341     //      *   The individual multiplications with the accumulator use the
2342     //      *   same math context settings as in {@code mc} except for a
2343     //      *   precision increased to {@code mc.precision + elength + 1}
2344     //      *   where {@code elength} is the number of decimal digits in
2345     //      *   {@code n}.
2346     //      *
2347     //      *   <li> if {@code n} is negative, the result is calculated as if
2348     //      *   {@code n} were positive; this value is then divided into one
2349     //      *   using the working precision specified above.
2350     //      *
2351     //      *   <li> The final value from either the positive or negative case
2352     //      *   is then rounded to the destination precision.
2353     //      *   </ul>
2354     //      * </ul>
2355     //      *
2356     //      * @param  n power to raise this {@code BigDecimal} to.
2357     //      * @param  mc the context to use.
2358     //      * @return <code>this!(sup)n</sup></code> using the ANSI standard X3.274-1996
2359     //      *         algorithm
2360     //      * @throws ArithmeticException if the result is inexact but the
2361     //      *         rounding mode is {@code UNNECESSARY}, or {@code n} is out
2362     //      *         of range.
2363     //      */
2364     //     BigDecimal pow(int n, MathContext mc) {
2365     //         if (mc.precision == 0)
2366     //             return pow(n);
2367     //         if (n < -999999999 || n > 999999999)
2368     //             throw new ArithmeticException("Invalid operation");
2369     //         if (n == 0)
2370     //             return ONE;                      // x**0 == 1 in X3.274
2371     //         BigDecimal lhs = this;
2372     //         MathContext workmc = mc;           // working settings
2373     //         int mag = MathHelper.abs(n);               // magnitude of n
2374     //         if (mc.precision > 0) {
2375     //             int elength = longDigitLength(mag); // length of n in digits
2376     //             if (elength > mc.precision)        // X3.274 rule
2377     //                 throw new ArithmeticException("Invalid operation");
2378     //             workmc = new MathContext(mc.precision + elength + 1,
2379     //                                       mc.roundingMode);
2380     //         }
2381     //         // ready to carry out power calculation...
2382     //         BigDecimal acc = ONE;           // accumulator
2383     //         bool seenbit = false;        // set once we've seen a 1-bit
2384     //         for (int i=1;;i++) {            // for each bit [top bit ignored]
2385     //             mag += mag;                 // shift left 1 bit
2386     //             if (mag < 0) {              // top bit is set
2387     //                 seenbit = true;         // OK, we're off
2388     //                 acc = acc.multiply(lhs, workmc); // acc=acc*x
2389     //             }
2390     //             if (i == 31)
2391     //                 break;                  // that was the last bit
2392     //             if (seenbit)
2393     //                 acc=acc.multiply(acc, workmc);   // acc=acc*acc [square]
2394     //                 // else (!seenbit) no point in squaring ONE
2395     //         }
2396     //         // if negative n, calculate the reciprocal using working precision
2397     //         if (n < 0) // [hence mc.precision>0]
2398     //             acc=ONE.divide(acc, workmc);
2399     //         // round to final precision and strip zeros
2400     //         return doRound(acc, mc);
2401     //     }
2402 
2403     //     /**
2404     //      * Returns a {@code BigDecimal} whose value is the absolute value
2405     //      * of this {@code BigDecimal}, and whose scale is
2406     //      * {@code this.scale()}.
2407     //      *
2408     //      * @return {@code abs(this)}
2409     //      */
2410     //     BigDecimal abs() {
2411     //         return (signum() < 0 ? negate() : this);
2412     //     }
2413 
2414     //     /**
2415     //      * Returns a {@code BigDecimal} whose value is the absolute value
2416     //      * of this {@code BigDecimal}, with rounding according to the
2417     //      * context settings.
2418     //      *
2419     //      * @param mc the context to use.
2420     //      * @return {@code abs(this)}, rounded as necessary.
2421     //      * @throws ArithmeticException if the result is inexact but the
2422     //      *         rounding mode is {@code UNNECESSARY}.
2423     //      */
2424     //     BigDecimal abs(MathContext mc) {
2425     //         return (signum() < 0 ? negate(mc) : plus(mc));
2426     //     }
2427 
2428     //     /**
2429     //      * Returns a {@code BigDecimal} whose value is {@code (-this)},
2430     //      * and whose scale is {@code this.scale()}.
2431     //      *
2432     //      * @return {@code -this}.
2433     //      */
2434     //     BigDecimal negate() {
2435     //         if (intCompact == INFLATED) {
2436     //             return new BigDecimal(intVal.negate(), INFLATED, scale, precision);
2437     //         } else {
2438     //             return valueOf(-intCompact, scale, precision);
2439     //         }
2440     //     }
2441 
2442     //     /**
2443     //      * Returns a {@code BigDecimal} whose value is {@code (-this)},
2444     //      * with rounding according to the context settings.
2445     //      *
2446     //      * @param mc the context to use.
2447     //      * @return {@code -this}, rounded as necessary.
2448     //      * @throws ArithmeticException if the result is inexact but the
2449     //      *         rounding mode is {@code UNNECESSARY}.
2450     //      */
2451     //     BigDecimal negate(MathContext mc) {
2452     //         return negate().plus(mc);
2453     //     }
2454 
2455     //     /**
2456     //      * Returns a {@code BigDecimal} whose value is {@code (+this)}, and whose
2457     //      * scale is {@code this.scale()}.
2458     //      *
2459     //      * <p>This method, which simply returns this {@code BigDecimal}
2460     //      * is included for symmetry with the unary minus method {@link
2461     //      * #negate()}.
2462     //      *
2463     //      * @return {@code this}.
2464     //      * @see #negate()
2465     //      */
2466     //     BigDecimal plus() {
2467     //         return this;
2468     //     }
2469 
2470     //     /**
2471     //      * Returns a {@code BigDecimal} whose value is {@code (+this)},
2472     //      * with rounding according to the context settings.
2473     //      *
2474     //      * <p>The effect of this method is identical to that of the {@link
2475     //      * #round(MathContext)} method.
2476     //      *
2477     //      * @param mc the context to use.
2478     //      * @return {@code this}, rounded as necessary.  A zero result will
2479     //      *         have a scale of 0.
2480     //      * @throws ArithmeticException if the result is inexact but the
2481     //      *         rounding mode is {@code UNNECESSARY}.
2482     //      * @see    #round(MathContext)
2483     //      */
2484     //     BigDecimal plus(MathContext mc) {
2485     //         if (mc.precision == 0)                 // no rounding please
2486     //             return this;
2487     //         return doRound(this, mc);
2488     //     }
2489 
2490     //     /**
2491     //      * Returns the signum function of this {@code BigDecimal}.
2492     //      *
2493     //      * @return -1, 0, or 1 as the value of this {@code BigDecimal}
2494     //      *         is negative, zero, or positive.
2495     //      */
2496     int signum()
2497     {
2498         return (intCompact != INFLATED) ? Long.signum(intCompact) : intVal.signum();
2499     }
2500 
2501     /**
2502      * Returns the <i>scale</i> of this {@code BigDecimal}.  If zero
2503      * or positive, the scale is the number of digits to the right of
2504      * the decimal point.  If negative, the unscaled value of the
2505      * number is multiplied by ten to the power of the negation of the
2506      * scale.  For example, a scale of {@code -3} means the unscaled
2507      * value is multiplied by 1000.
2508      *
2509      * @return the scale of this {@code BigDecimal}.
2510      */
2511     int scale()
2512     {
2513         return _scale;
2514     }
2515 
2516     //     /**
2517     //      * Returns the <i>precision</i> of this {@code BigDecimal}.  (The
2518     //      * precision is the number of digits in the unscaled value.)
2519     //      *
2520     //      * <p>The precision of a zero value is 1.
2521     //      *
2522     //      * @return the precision of this {@code BigDecimal}.
2523     //      */
2524     //     int precision() {
2525     //         int result = precision;
2526     //         if (result == 0) {
2527     //             long s = intCompact;
2528     //             if (s != INFLATED)
2529     //                 result = longDigitLength(s);
2530     //             else
2531     //                 result = bigDigitLength(intVal);
2532     //             precision = result;
2533     //         }
2534     //         return result;
2535     //     }
2536 
2537     //     /**
2538     //      * Returns a {@code BigInteger} whose value is the <i>unscaled
2539     //      * value</i> of this {@code BigDecimal}.  (Computes <code>(this *
2540     //      * 10!(sup)this.scale()</sup>)</code>.)
2541     //      *
2542     //      * @return the unscaled value of this {@code BigDecimal}.
2543     //      */
2544     //     BigInteger unscaledValue() {
2545     //         return this.inflated();
2546     //     }
2547 
2548     //     // Rounding Modes
2549 
2550     //     /**
2551     //      * Rounding mode to round away from zero.  Always increments the
2552     //      * digit prior to a nonzero discarded fraction.  Note that this rounding
2553     //      * mode never decreases the magnitude of the calculated value.
2554     //      *
2555     //      * @deprecated Use {@link RoundingMode#UP} instead.
2556     //      */
2557     //     //@Deprecated(since="9")
2558     enum int ROUND_UP = 0;
2559 
2560     //     /**
2561     //      * Rounding mode to round towards zero.  Never increments the digit
2562     //      * prior to a discarded fraction (i.e., truncates).  Note that this
2563     //      * rounding mode never increases the magnitude of the calculated value.
2564     //      *
2565     //      * @deprecated Use {@link RoundingMode#DOWN} instead.
2566     //      */
2567     //     //@Deprecated(since="9")
2568     enum int ROUND_DOWN = 1;
2569 
2570     //     /**
2571     //      * Rounding mode to round towards positive infinity.  If the
2572     //      * {@code BigDecimal} is positive, behaves as for
2573     //      * {@code ROUND_UP}; if negative, behaves as for
2574     //      * {@code ROUND_DOWN}.  Note that this rounding mode never
2575     //      * decreases the calculated value.
2576     //      *
2577     //      * @deprecated Use {@link RoundingMode#CEILING} instead.
2578     //      */
2579     //     //@Deprecated(since="9")
2580     enum int ROUND_CEILING = 2;
2581 
2582     //     /**
2583     //      * Rounding mode to round towards negative infinity.  If the
2584     //      * {@code BigDecimal} is positive, behave as for
2585     //      * {@code ROUND_DOWN}; if negative, behave as for
2586     //      * {@code ROUND_UP}.  Note that this rounding mode never
2587     //      * increases the calculated value.
2588     //      *
2589     //      * @deprecated Use {@link RoundingMode#FLOOR} instead.
2590     //      */
2591     //     //@Deprecated(since="9")
2592     enum int ROUND_FLOOR = 3;
2593 
2594     //     /**
2595     //      * Rounding mode to round towards {@literal "nearest neighbor"}
2596     //      * unless both neighbors are equidistant, in which case round up.
2597     //      * Behaves as for {@code ROUND_UP} if the discarded fraction is
2598     //      * &ge; 0.5; otherwise, behaves as for {@code ROUND_DOWN}.  Note
2599     //      * that this is the rounding mode that most of us were taught in
2600     //      * grade school.
2601     //      *
2602     //      * @deprecated Use {@link RoundingMode#HALF_UP} instead.
2603     //      */
2604     //     //@Deprecated(since="9")
2605     enum int ROUND_HALF_UP = 4;
2606 
2607     //     /**
2608     //      * Rounding mode to round towards {@literal "nearest neighbor"}
2609     //      * unless both neighbors are equidistant, in which case round
2610     //      * down.  Behaves as for {@code ROUND_UP} if the discarded
2611     //      * fraction is {@literal >} 0.5; otherwise, behaves as for
2612     //      * {@code ROUND_DOWN}.
2613     //      *
2614     //      * @deprecated Use {@link RoundingMode#HALF_DOWN} instead.
2615     //      */
2616     //     //@Deprecated(since="9")
2617     enum int ROUND_HALF_DOWN = 5;
2618 
2619     //     /**
2620     //      * Rounding mode to round towards the {@literal "nearest neighbor"}
2621     //      * unless both neighbors are equidistant, in which case, round
2622     //      * towards the even neighbor.  Behaves as for
2623     //      * {@code ROUND_HALF_UP} if the digit to the left of the
2624     //      * discarded fraction is odd; behaves as for
2625     //      * {@code ROUND_HALF_DOWN} if it's even.  Note that this is the
2626     //      * rounding mode that minimizes cumulative error when applied
2627     //      * repeatedly over a sequence of calculations.
2628     //      *
2629     //      * @deprecated Use {@link RoundingMode#HALF_EVEN} instead.
2630     //      */
2631     //     //@Deprecated(since="9")
2632     enum int ROUND_HALF_EVEN = 6;
2633 
2634     //     /**
2635     //      * Rounding mode to assert that the requested operation has an exact
2636     //      * result, hence no rounding is necessary.  If this rounding mode is
2637     //      * specified on an operation that yields an inexact result, an
2638     //      * {@code ArithmeticException} is thrown.
2639     //      *
2640     //      * @deprecated Use {@link RoundingMode#UNNECESSARY} instead.
2641     //      */
2642     //     //@Deprecated(since="9")
2643     enum int ROUND_UNNECESSARY = 7;
2644 
2645     //     // Scaling/Rounding Operations
2646 
2647     //     /**
2648     //      * Returns a {@code BigDecimal} rounded according to the
2649     //      * {@code MathContext} settings.  If the precision setting is 0 then
2650     //      * no rounding takes place.
2651     //      *
2652     //      * <p>The effect of this method is identical to that of the
2653     //      * {@link #plus(MathContext)} method.
2654     //      *
2655     //      * @param mc the context to use.
2656     //      * @return a {@code BigDecimal} rounded according to the
2657     //      *         {@code MathContext} settings.
2658     //      * @throws ArithmeticException if the rounding mode is
2659     //      *         {@code UNNECESSARY} and the
2660     //      *         {@code BigDecimal}  operation would require rounding.
2661     //      * @see    #plus(MathContext)
2662     //      */
2663     //     BigDecimal round(MathContext mc) {
2664     //         return plus(mc);
2665     //     }
2666 
2667     //     /**
2668     //      * Returns a {@code BigDecimal} whose scale is the specified
2669     //      * value, and whose unscaled value is determined by multiplying or
2670     //      * dividing this {@code BigDecimal}'s unscaled value by the
2671     //      * appropriate power of ten to maintain its overall value.  If the
2672     //      * scale is reduced by the operation, the unscaled value must be
2673     //      * divided (rather than multiplied), and the value may be changed;
2674     //      * in this case, the specified rounding mode is applied to the
2675     //      * division.
2676     //      *
2677     //      * @apiNote Since BigDecimal objects are immutable, calls of
2678     //      * this method do <em>not</em> result in the original object being
2679     //      * modified, contrary to the usual convention of having methods
2680     //      * named <code>set!(i)X</i></code> mutate field <i>{@code X}</i>.
2681     //      * Instead, {@code setScale} returns an object with the proper
2682     //      * scale; the returned object may or may not be newly allocated.
2683     //      *
2684     //      * @param  newScale scale of the {@code BigDecimal} value to be returned.
2685     //      * @param  roundingMode The rounding mode to apply.
2686     //      * @return a {@code BigDecimal} whose scale is the specified value,
2687     //      *         and whose unscaled value is determined by multiplying or
2688     //      *         dividing this {@code BigDecimal}'s unscaled value by the
2689     //      *         appropriate power of ten to maintain its overall value.
2690     //      * @throws ArithmeticException if {@code roundingMode==UNNECESSARY}
2691     //      *         and the specified scaling operation would require
2692     //      *         rounding.
2693     //      * @see    RoundingMode
2694     //      */
2695     //     BigDecimal setScale(int newScale, RoundingMode roundingMode) {
2696     //         return setScale(newScale, roundingMode.oldMode);
2697     //     }
2698 
2699     //     /**
2700     //      * Returns a {@code BigDecimal} whose scale is the specified
2701     //      * value, and whose unscaled value is determined by multiplying or
2702     //      * dividing this {@code BigDecimal}'s unscaled value by the
2703     //      * appropriate power of ten to maintain its overall value.  If the
2704     //      * scale is reduced by the operation, the unscaled value must be
2705     //      * divided (rather than multiplied), and the value may be changed;
2706     //      * in this case, the specified rounding mode is applied to the
2707     //      * division.
2708     //      *
2709     //      * @apiNote Since BigDecimal objects are immutable, calls of
2710     //      * this method do <em>not</em> result in the original object being
2711     //      * modified, contrary to the usual convention of having methods
2712     //      * named <code>set!(i)X</i></code> mutate field <i>{@code X}</i>.
2713     //      * Instead, {@code setScale} returns an object with the proper
2714     //      * scale; the returned object may or may not be newly allocated.
2715     //      *
2716     //      * @deprecated The method {@link #setScale(int, RoundingMode)} should
2717     //      * be used in preference to this legacy method.
2718     //      *
2719     //      * @param  newScale scale of the {@code BigDecimal} value to be returned.
2720     //      * @param  roundingMode The rounding mode to apply.
2721     //      * @return a {@code BigDecimal} whose scale is the specified value,
2722     //      *         and whose unscaled value is determined by multiplying or
2723     //      *         dividing this {@code BigDecimal}'s unscaled value by the
2724     //      *         appropriate power of ten to maintain its overall value.
2725     //      * @throws ArithmeticException if {@code roundingMode==ROUND_UNNECESSARY}
2726     //      *         and the specified scaling operation would require
2727     //      *         rounding.
2728     //      * @throws IllegalArgumentException if {@code roundingMode} does not
2729     //      *         represent a valid rounding mode.
2730     //      * @see    #ROUND_UP
2731     //      * @see    #ROUND_DOWN
2732     //      * @see    #ROUND_CEILING
2733     //      * @see    #ROUND_FLOOR
2734     //      * @see    #ROUND_HALF_UP
2735     //      * @see    #ROUND_HALF_DOWN
2736     //      * @see    #ROUND_HALF_EVEN
2737     //      * @see    #ROUND_UNNECESSARY
2738     //      */
2739     //     //@Deprecated(since="9")
2740     //     BigDecimal setScale(int newScale, int roundingMode) {
2741     //         if (roundingMode < ROUND_UP || roundingMode > ROUND_UNNECESSARY)
2742     //             throw new IllegalArgumentException("Invalid rounding mode");
2743 
2744     //         int oldScale = this.scale;
2745     //         if (newScale == oldScale)        // easy case
2746     //             return this;
2747     //         if (this.signum() == 0)            // zero can have any scale
2748     //             return zeroValueOf(newScale);
2749     //         if(this.intCompact!=INFLATED) {
2750     //             long rs = this.intCompact;
2751     //             if (newScale > oldScale) {
2752     //                 int raise = checkScale((long) newScale - oldScale);
2753     //                 if ((rs = longMultiplyPowerTen(rs, raise)) != INFLATED) {
2754     //                     return valueOf(rs,newScale);
2755     //                 }
2756     //                 BigInteger rb = bigMultiplyPowerTen(raise);
2757     //                 return new BigDecimal(rb, INFLATED, newScale, (precision > 0) ? precision + raise : 0);
2758     //             } else {
2759     //                 // newScale < oldScale -- drop some digits
2760     //                 // Can't predict the precision due to the effect of rounding.
2761     //                 int drop = checkScale((long) oldScale - newScale);
2762     //                 if (drop < LONG_TEN_POWERS_TABLE.length) {
2763     //                     return divideAndRound(rs, LONG_TEN_POWERS_TABLE[drop], newScale, roundingMode, newScale);
2764     //                 } else {
2765     //                     return divideAndRound(this.inflated(), bigTenToThe(drop), newScale, roundingMode, newScale);
2766     //                 }
2767     //             }
2768     //         } else {
2769     //             if (newScale > oldScale) {
2770     //                 int raise = checkScale((long) newScale - oldScale);
2771     //                 BigInteger rb = bigMultiplyPowerTen(this.intVal,raise);
2772     //                 return new BigDecimal(rb, INFLATED, newScale, (precision > 0) ? precision + raise : 0);
2773     //             } else {
2774     //                 // newScale < oldScale -- drop some digits
2775     //                 // Can't predict the precision due to the effect of rounding.
2776     //                 int drop = checkScale((long) oldScale - newScale);
2777     //                 if (drop < LONG_TEN_POWERS_TABLE.length)
2778     //                     return divideAndRound(this.intVal, LONG_TEN_POWERS_TABLE[drop], newScale, roundingMode,
2779     //                                           newScale);
2780     //                 else
2781     //                     return divideAndRound(this.intVal,  bigTenToThe(drop), newScale, roundingMode, newScale);
2782     //             }
2783     //         }
2784     //     }
2785 
2786     //     /**
2787     //      * Returns a {@code BigDecimal} whose scale is the specified
2788     //      * value, and whose value is numerically equal to this
2789     //      * {@code BigDecimal}'s.  Throws an {@code ArithmeticException}
2790     //      * if this is not possible.
2791     //      *
2792     //      * <p>This call is typically used to increase the scale, in which
2793     //      * case it is guaranteed that there exists a {@code BigDecimal}
2794     //      * of the specified scale and the correct value.  The call can
2795     //      * also be used to reduce the scale if the caller knows that the
2796     //      * {@code BigDecimal} has sufficiently many zeros at the end of
2797     //      * its fractional part (i.e., factors of ten in its integer value)
2798     //      * to allow for the rescaling without changing its value.
2799     //      *
2800     //      * <p>This method returns the same result as the two-argument
2801     //      * versions of {@code setScale}, but saves the caller the trouble
2802     //      * of specifying a rounding mode in cases where it is irrelevant.
2803     //      *
2804     //      * @apiNote Since {@code BigDecimal} objects are immutable,
2805     //      * calls of this method do <em>not</em> result in the original
2806     //      * object being modified, contrary to the usual convention of
2807     //      * having methods named <code>set!(i)X</i></code> mutate field
2808     //      * <i>{@code X}</i>.  Instead, {@code setScale} returns an
2809     //      * object with the proper scale; the returned object may or may
2810     //      * not be newly allocated.
2811     //      *
2812     //      * @param  newScale scale of the {@code BigDecimal} value to be returned.
2813     //      * @return a {@code BigDecimal} whose scale is the specified value, and
2814     //      *         whose unscaled value is determined by multiplying or dividing
2815     //      *         this {@code BigDecimal}'s unscaled value by the appropriate
2816     //      *         power of ten to maintain its overall value.
2817     //      * @throws ArithmeticException if the specified scaling operation would
2818     //      *         require rounding.
2819     //      * @see    #setScale(int, int)
2820     //      * @see    #setScale(int, RoundingMode)
2821     //      */
2822     BigDecimal setScale(int newScale, int t)
2823     {
2824         // return setScale(newScale, ROUND_UNNECESSARY);
2825         _scale = newScale;
2826         return this;
2827     }
2828 
2829     BigDecimal setScale(int newScale)
2830     {
2831         // return setScale(newScale, ROUND_UNNECESSARY);
2832         _scale = newScale;
2833         return this;
2834     }
2835 
2836     //     // Decimal Point Motion Operations
2837 
2838     //     /**
2839     //      * Returns a {@code BigDecimal} which is equivalent to this one
2840     //      * with the decimal point moved {@code n} places to the left.  If
2841     //      * {@code n} is non-negative, the call merely adds {@code n} to
2842     //      * the scale.  If {@code n} is negative, the call is equivalent
2843     //      * to {@code movePointRight(-n)}.  The {@code BigDecimal}
2844     //      * returned by this call has value <code>(this &times;
2845     //      * 10!(sup)-n</sup>)</code> and scale {@code max(this.scale()+n,
2846     //      * 0)}.
2847     //      *
2848     //      * @param  n number of places to move the decimal point to the left.
2849     //      * @return a {@code BigDecimal} which is equivalent to this one with the
2850     //      *         decimal point moved {@code n} places to the left.
2851     //      * @throws ArithmeticException if scale overflows.
2852     //      */
2853     BigDecimal movePointLeft(int n)
2854     {
2855         // Cannot use movePointRight(-n) in case of n==Integer.MIN_VALUE
2856         int newScale = checkScale(cast(long) scale + n);
2857         BigDecimal num = new BigDecimal(intVal, intCompact, newScale, 0);
2858         return num.scale < 0 ? num.setScale(0, ROUND_UNNECESSARY) : num;
2859     }
2860 
2861     //     /**
2862     //      * Returns a {@code BigDecimal} which is equivalent to this one
2863     //      * with the decimal point moved {@code n} places to the right.
2864     //      * If {@code n} is non-negative, the call merely subtracts
2865     //      * {@code n} from the scale.  If {@code n} is negative, the call
2866     //      * is equivalent to {@code movePointLeft(-n)}.  The
2867     //      * {@code BigDecimal} returned by this call has value <code>(this
2868     //      * &times; 10!(sup)n</sup>)</code> and scale {@code max(this.scale()-n,
2869     //      * 0)}.
2870     //      *
2871     //      * @param  n number of places to move the decimal point to the right.
2872     //      * @return a {@code BigDecimal} which is equivalent to this one
2873     //      *         with the decimal point moved {@code n} places to the right.
2874     //      * @throws ArithmeticException if scale overflows.
2875     //      */
2876     BigDecimal movePointRight(int n)
2877     {
2878         // Cannot use movePointLeft(-n) in case of n==Integer.MIN_VALUE
2879         int newScale = checkScale(cast(long) scale - n);
2880         BigDecimal num = new BigDecimal(intVal, intCompact, newScale, 0);
2881         return num.scale < 0 ? num.setScale(0, ROUND_UNNECESSARY) : num;
2882     }
2883 
2884     //     /**
2885     //      * Returns a BigDecimal whose numerical value is equal to
2886     //      * ({@code this} * 10!(sup)n</sup>).  The scale of
2887     //      * the result is {@code (this.scale() - n)}.
2888     //      *
2889     //      * @param n the exponent power of ten to scale by
2890     //      * @return a BigDecimal whose numerical value is equal to
2891     //      * ({@code this} * 10!(sup)n</sup>)
2892     //      * @throws ArithmeticException if the scale would be
2893     //      *         outside the range of a 32-bit integer.
2894     //      *
2895     //      */
2896     //     BigDecimal scaleByPowerOfTen(int n) {
2897     //         return new BigDecimal(intVal, intCompact,
2898     //                               checkScale((long)scale - n), precision);
2899     //     }
2900 
2901     //     /**
2902     //      * Returns a {@code BigDecimal} which is numerically equal to
2903     //      * this one but with any trailing zeros removed from the
2904     //      * representation.  For example, stripping the trailing zeros from
2905     //      * the {@code BigDecimal} value {@code 600.0}, which has
2906     //      * [{@code BigInteger}, {@code scale}] components equals to
2907     //      * [6000, 1], yields {@code 6E2} with [{@code BigInteger},
2908     //      * {@code scale}] components equals to [6, -2].  If
2909     //      * this BigDecimal is numerically equal to zero, then
2910     //      * {@code BigDecimal.ZERO} is returned.
2911     //      *
2912     //      * @return a numerically equal {@code BigDecimal} with any
2913     //      * trailing zeros removed.
2914     //      */
2915     //     BigDecimal stripTrailingZeros() {
2916     //         if (intCompact == 0 || (intVal !is null && intVal.signum() == 0)) {
2917     //             return BigDecimal.ZERO;
2918     //         } else if (intCompact != INFLATED) {
2919     //             return createAndStripZerosToMatchScale(intCompact, scale, Long.MIN_VALUE);
2920     //         } else {
2921     //             return createAndStripZerosToMatchScale(intVal, scale, Long.MIN_VALUE);
2922     //         }
2923     //     }
2924 
2925     //     // Comparison Operations
2926 
2927     //     /**
2928     //      * Compares this {@code BigDecimal} with the specified
2929     //      * {@code BigDecimal}.  Two {@code BigDecimal} objects that are
2930     //      * equal in value but have a different scale (like 2.0 and 2.00)
2931     //      * are considered equal by this method.  This method is provided
2932     //      * in preference to individual methods for each of the six bool
2933     //      * comparison operators ({@literal <}, ==,
2934     //      * {@literal >}, {@literal >=}, !=, {@literal <=}).  The
2935     //      * suggested idiom for performing these comparisons is:
2936     //      * {@code (x.compareTo(y)} &lt;<i>op</i>&gt; {@code 0)}, where
2937     //      * &lt;<i>op</i>&gt; is one of the six comparison operators.
2938     //      *
2939     //      * @param  val {@code BigDecimal} to which this {@code BigDecimal} is
2940     //      *         to be compared.
2941     //      * @return -1, 0, or 1 as this {@code BigDecimal} is numerically
2942     //      *          less than, equal to, or greater than {@code val}.
2943     //      */
2944     //     @Override
2945     //     int compareTo(BigDecimal val) {
2946     //         // Quick path for equal scale and non-inflated case.
2947     //         if (scale == val.scale) {
2948     //             long xs = intCompact;
2949     //             long ys = val.intCompact;
2950     //             if (xs != INFLATED && ys != INFLATED)
2951     //                 return xs != ys ? ((xs > ys) ? 1 : -1) : 0;
2952     //         }
2953     //         int xsign = this.signum();
2954     //         int ysign = val.signum();
2955     //         if (xsign != ysign)
2956     //             return (xsign > ysign) ? 1 : -1;
2957     //         if (xsign == 0)
2958     //             return 0;
2959     //         int cmp = compareMagnitude(val);
2960     //         return (xsign > 0) ? cmp : -cmp;
2961     //     }
2962 
2963     //     /**
2964     //      * Version of compareTo that ignores sign.
2965     //      */
2966     //     private int compareMagnitude(BigDecimal val) {
2967     //         // Match scales, avoid unnecessary inflation
2968     //         long ys = val.intCompact;
2969     //         long xs = this.intCompact;
2970     //         if (xs == 0)
2971     //             return (ys == 0) ? 0 : -1;
2972     //         if (ys == 0)
2973     //             return 1;
2974 
2975     //         long sdiff = (long)this.scale - val.scale;
2976     //         if (sdiff != 0) {
2977     //             // Avoid matching scales if the (adjusted) exponents differ
2978     //             long xae = (long)this.precision() - this.scale;   // [-1]
2979     //             long yae = (long)val.precision() - val.scale;     // [-1]
2980     //             if (xae < yae)
2981     //                 return -1;
2982     //             if (xae > yae)
2983     //                 return 1;
2984     //             if (sdiff < 0) {
2985     //                 // The cases sdiff <= Integer.MIN_VALUE intentionally fall through.
2986     //                 if ( sdiff > Integer.MIN_VALUE &&
2987     //                       (xs == INFLATED ||
2988     //                       (xs = longMultiplyPowerTen(xs, (int)-sdiff)) == INFLATED) &&
2989     //                      ys == INFLATED) {
2990     //                     BigInteger rb = bigMultiplyPowerTen((int)-sdiff);
2991     //                     return rb.compareMagnitude(val.intVal);
2992     //                 }
2993     //             } else { // sdiff > 0
2994     //                 // The cases sdiff > Integer.MAX_VALUE intentionally fall through.
2995     //                 if ( sdiff <= Integer.MAX_VALUE &&
2996     //                       (ys == INFLATED ||
2997     //                       (ys = longMultiplyPowerTen(ys, (int)sdiff)) == INFLATED) &&
2998     //                      xs == INFLATED) {
2999     //                     BigInteger rb = val.bigMultiplyPowerTen((int)sdiff);
3000     //                     return this.intVal.compareMagnitude(rb);
3001     //                 }
3002     //             }
3003     //         }
3004     //         if (xs != INFLATED)
3005     //             return (ys != INFLATED) ? longCompareMagnitude(xs, ys) : -1;
3006     //         else if (ys != INFLATED)
3007     //             return 1;
3008     //         else
3009     //             return this.intVal.compareMagnitude(val.intVal);
3010     //     }
3011 
3012     //     /**
3013     //      * Compares this {@code BigDecimal} with the specified
3014     //      * {@code Object} for equality.  Unlike {@link
3015     //      * #compareTo(BigDecimal) compareTo}, this method considers two
3016     //      * {@code BigDecimal} objects equal only if they are equal in
3017     //      * value and scale (thus 2.0 is not equal to 2.00 when compared by
3018     //      * this method).
3019     //      *
3020     //      * @param  x {@code Object} to which this {@code BigDecimal} is
3021     //      *         to be compared.
3022     //      * @return {@code true} if and only if the specified {@code Object} is a
3023     //      *         {@code BigDecimal} whose value and scale are equal to this
3024     //      *         {@code BigDecimal}'s.
3025     //      * @see    #compareTo(java.math.BigDecimal)
3026     //      * @see    #hashCode
3027     //      */
3028     //     @Override
3029     //     bool equals(Object x) {
3030     //         if (!(x instanceof BigDecimal))
3031     //             return false;
3032     //         BigDecimal xDec = (BigDecimal) x;
3033     //         if (x == this)
3034     //             return true;
3035     //         if (scale != xDec.scale)
3036     //             return false;
3037     //         long s = this.intCompact;
3038     //         long xs = xDec.intCompact;
3039     //         if (s != INFLATED) {
3040     //             if (xs == INFLATED)
3041     //                 xs = compactValFor(xDec.intVal);
3042     //             return xs == s;
3043     //         } else if (xs != INFLATED)
3044     //             return xs == compactValFor(this.intVal);
3045 
3046     //         return this.inflated().equals(xDec.inflated());
3047     //     }
3048 
3049     //     /**
3050     //      * Returns the minimum of this {@code BigDecimal} and
3051     //      * {@code val}.
3052     //      *
3053     //      * @param  val value with which the minimum is to be computed.
3054     //      * @return the {@code BigDecimal} whose value is the lesser of this
3055     //      *         {@code BigDecimal} and {@code val}.  If they are equal,
3056     //      *         as defined by the {@link #compareTo(BigDecimal) compareTo}
3057     //      *         method, {@code this} is returned.
3058     //      * @see    #compareTo(java.math.BigDecimal)
3059     //      */
3060     //     BigDecimal min(BigDecimal val) {
3061     //         return (compareTo(val) <= 0 ? this : val);
3062     //     }
3063 
3064     //     /**
3065     //      * Returns the maximum of this {@code BigDecimal} and {@code val}.
3066     //      *
3067     //      * @param  val value with which the maximum is to be computed.
3068     //      * @return the {@code BigDecimal} whose value is the greater of this
3069     //      *         {@code BigDecimal} and {@code val}.  If they are equal,
3070     //      *         as defined by the {@link #compareTo(BigDecimal) compareTo}
3071     //      *         method, {@code this} is returned.
3072     //      * @see    #compareTo(java.math.BigDecimal)
3073     //      */
3074     //     BigDecimal max(BigDecimal val) {
3075     //         return (compareTo(val) >= 0 ? this : val);
3076     //     }
3077 
3078     //     // Hash Function
3079 
3080     //     /**
3081     //      * Returns the hash code for this {@code BigDecimal}.  Note that
3082     //      * two {@code BigDecimal} objects that are numerically equal but
3083     //      * differ in scale (like 2.0 and 2.00) will generally <em>not</em>
3084     //      * have the same hash code.
3085     //      *
3086     //      * @return hash code for this {@code BigDecimal}.
3087     //      * @see #equals(Object)
3088     //      */
3089     //     @Override
3090     //     int hashCode() {
3091     //         if (intCompact != INFLATED) {
3092     //             long val2 = (intCompact < 0)? -intCompact : intCompact;
3093     //             int temp = (int)( ((int)(val2 >>> 32)) * 31  +
3094     //                               (val2 & LONG_MASK));
3095     //             return 31*((intCompact < 0) ?-temp:temp) + scale;
3096     //         } else
3097     //             return 31*intVal.hashCode() + scale;
3098     //     }
3099 
3100     //     // Format Converters
3101 
3102     //     /**
3103     //      * Returns the string representation of this {@code BigDecimal},
3104     //      * using scientific notation if an exponent is needed.
3105     //      *
3106     //      * <p>A standard canonical string form of the {@code BigDecimal}
3107     //      * is created as though by the following steps: first, the
3108     //      * absolute value of the unscaled value of the {@code BigDecimal}
3109     //      * is converted to a string in base ten using the characters
3110     //      * {@code '0'} through {@code '9'} with no leading zeros (except
3111     //      * if its value is zero, in which case a single {@code '0'}
3112     //      * character is used).
3113     //      *
3114     //      * <p>Next, an <i>adjusted exponent</i> is calculated; this is the
3115     //      * negated scale, plus the number of characters in the converted
3116     //      * unscaled value, less one.  That is,
3117     //      * {@code -scale+(ulength-1)}, where {@code ulength} is the
3118     //      * length of the absolute value of the unscaled value in decimal
3119     //      * digits (its <i>precision</i>).
3120     //      *
3121     //      * <p>If the scale is greater than or equal to zero and the
3122     //      * adjusted exponent is greater than or equal to {@code -6}, the
3123     //      * number will be converted to a character form without using
3124     //      * exponential notation.  In this case, if the scale is zero then
3125     //      * no decimal point is added and if the scale is positive a
3126     //      * decimal point will be inserted with the scale specifying the
3127     //      * number of characters to the right of the decimal point.
3128     //      * {@code '0'} characters are added to the left of the converted
3129     //      * unscaled value as necessary.  If no character precedes the
3130     //      * decimal point after this insertion then a conventional
3131     //      * {@code '0'} character is prefixed.
3132     //      *
3133     //      * <p>Otherwise (that is, if the scale is negative, or the
3134     //      * adjusted exponent is less than {@code -6}), the number will be
3135     //      * converted to a character form using exponential notation.  In
3136     //      * this case, if the converted {@code BigInteger} has more than
3137     //      * one digit a decimal point is inserted after the first digit.
3138     //      * An exponent in character form is then suffixed to the converted
3139     //      * unscaled value (perhaps with inserted decimal point); this
3140     //      * comprises the letter {@code 'E'} followed immediately by the
3141     //      * adjusted exponent converted to a character form.  The latter is
3142     //      * in base ten, using the characters {@code '0'} through
3143     //      * {@code '9'} with no leading zeros, and is always prefixed by a
3144     //      * sign character {@code '-'} (<code>'&#92;u002D'</code>) if the
3145     //      * adjusted exponent is negative, {@code '+'}
3146     //      * (<code>'&#92;u002B'</code>) otherwise).
3147     //      *
3148     //      * <p>Finally, the entire string is prefixed by a minus sign
3149     //      * character {@code '-'} (<code>'&#92;u002D'</code>) if the unscaled
3150     //      * value is less than zero.  No sign character is prefixed if the
3151     //      * unscaled value is zero or positive.
3152     //      *
3153     //      * <p><b>Examples:</b>
3154     //      * <p>For each representation [<i>unscaled value</i>, <i>scale</i>]
3155     //      * on the left, the resulting string is shown on the right.
3156     //      * <pre>
3157     //      * [123,0]      "123"
3158     //      * [-123,0]     "-123"
3159     //      * [123,-1]     "1.23E+3"
3160     //      * [123,-3]     "1.23E+5"
3161     //      * [123,1]      "12.3"
3162     //      * [123,5]      "0.00123"
3163     //      * [123,10]     "1.23E-8"
3164     //      * [-123,12]    "-1.23E-10"
3165     //      * </pre>
3166     //      *
3167     //      * <b>Notes:</b>
3168     //      * <ol>
3169     //      *
3170     //      * <li>There is a one-to-one mapping between the distinguishable
3171     //      * {@code BigDecimal} values and the result of this conversion.
3172     //      * That is, every distinguishable {@code BigDecimal} value
3173     //      * (unscaled value and scale) has a unique string representation
3174     //      * as a result of using {@code toString}.  If that string
3175     //      * representation is converted back to a {@code BigDecimal} using
3176     //      * the {@link #BigDecimal(string)} constructor, then the original
3177     //      * value will be recovered.
3178     //      *
3179     //      * <li>The string produced for a given number is always the same;
3180     //      * it is not affected by locale.  This means that it can be used
3181     //      * as a canonical string representation for exchanging decimal
3182     //      * data, or as a key for a Hashtable, etc.  Locale-sensitive
3183     //      * number formatting and parsing is handled by the {@link
3184     //      * java.text.NumberFormat} class and its subclasses.
3185     //      *
3186     //      * <li>The {@link #toEngineeringString} method may be used for
3187     //      * presenting numbers with exponents in engineering notation, and the
3188     //      * {@link #setScale(int,RoundingMode) setScale} method may be used for
3189     //      * rounding a {@code BigDecimal} so it has a known number of digits after
3190     //      * the decimal point.
3191     //      *
3192     //      * <li>The digit-to-character mapping provided by
3193     //      * {@code Character.forDigit} is used.
3194     //      *
3195     //      * </ol>
3196     //      *
3197     //      * @return string representation of this {@code BigDecimal}.
3198     //      * @see    Character#forDigit
3199     //      * @see    #BigDecimal(java.lang.string)
3200     //      */
3201     //     @Override
3202     //     string toString() {
3203     //         string sc = stringCache;
3204     //         if (sc is null) {
3205     //             stringCache = sc = layoutChars(true);
3206     //         }
3207     //         return sc;
3208     //     }
3209 
3210     //     /**
3211     //      * Returns a string representation of this {@code BigDecimal},
3212     //      * using engineering notation if an exponent is needed.
3213     //      *
3214     //      * <p>Returns a string that represents the {@code BigDecimal} as
3215     //      * described in the {@link #toString()} method, except that if
3216     //      * exponential notation is used, the power of ten is adjusted to
3217     //      * be a multiple of three (engineering notation) such that the
3218     //      * integer part of nonzero values will be in the range 1 through
3219     //      * 999.  If exponential notation is used for zero values, a
3220     //      * decimal point and one or two fractional zero digits are used so
3221     //      * that the scale of the zero value is preserved.  Note that
3222     //      * unlike the output of {@link #toString()}, the output of this
3223     //      * method is <em>not</em> guaranteed to recover the same [integer,
3224     //      * scale] pair of this {@code BigDecimal} if the output string is
3225     //      * converting back to a {@code BigDecimal} using the {@linkplain
3226     //      * #BigDecimal(string) string constructor}.  The result of this method meets
3227     //      * the weaker constraint of always producing a numerically equal
3228     //      * result from applying the string constructor to the method's output.
3229     //      *
3230     //      * @return string representation of this {@code BigDecimal}, using
3231     //      *         engineering notation if an exponent is needed.
3232     //      */
3233     //     string toEngineeringString() {
3234     //         return layoutChars(false);
3235     //     }
3236 
3237     /**
3238      * Returns a string representation of this {@code BigDecimal}
3239      * without an exponent field.  For values with a positive scale,
3240      * the number of digits to the right of the decimal point is used
3241      * to indicate scale.  For values with a zero or negative scale,
3242      * the resulting string is generated as if the value were
3243      * converted to a numerically equal value with zero scale and as
3244      * if all the trailing zeros of the zero scale value were present
3245      * in the result.
3246      *
3247      * The entire string is prefixed by a minus sign character '-'
3248      * (<code>'&#92;u002D'</code>) if the unscaled value is less than
3249      * zero. No sign character is prefixed if the unscaled value is
3250      * zero or positive.
3251      *
3252      * Note that if the result of this method is passed to the
3253      * {@linkplain #BigDecimal(string) string constructor}, only the
3254      * numerical value of this {@code BigDecimal} will necessarily be
3255      * recovered; the representation of the new {@code BigDecimal}
3256      * may have a different scale.  In particular, if this
3257      * {@code BigDecimal} has a negative scale, the string resulting
3258      * from this method will have a scale of zero when processed by
3259      * the string constructor.
3260      *
3261      * (This method behaves analogously to the {@code toString}
3262      * method in 1.4 and earlier releases.)
3263      *
3264      * @return a string representation of this {@code BigDecimal}
3265      * without an exponent field.
3266      * @see #toString()
3267      * @see #toEngineeringString()
3268      */
3269     string toPlainString()
3270     {
3271         if (scale == 0)
3272         {
3273             if (intCompact != INFLATED)
3274             {
3275                 return to!string(intCompact);
3276             }
3277             else
3278             {
3279                 return intVal.toString();
3280             }
3281         }
3282         if (this.scale < 0)
3283         { // No decimal point
3284             if (signum() == 0)
3285             {
3286                 return "0";
3287             }
3288             int trailingZeros = checkScaleNonZero((-cast(long) scale));
3289             StringBuilder buf;
3290             if (intCompact != INFLATED)
3291             {
3292                 buf = new StringBuilder(20 + trailingZeros);
3293                 buf.append(intCompact);
3294             }
3295             else
3296             {
3297                 string str = intVal.toString();
3298                 buf = new StringBuilder(str.length + trailingZeros);
3299                 buf.append(str);
3300             }
3301             for (int i = 0; i < trailingZeros; i++)
3302             {
3303                 buf.append('0');
3304             }
3305             return buf.toString();
3306         }
3307         string str;
3308         if (intCompact != INFLATED)
3309         {
3310             str = to!string(MathHelper.abs(intCompact));
3311         }
3312         else
3313         {
3314             str = intVal.abs().toString();
3315         }
3316         return getValueString(signum(), str, scale);
3317     }
3318 
3319     //     /* Returns a digit.digit string */
3320     private string getValueString(int signum, string intString, int scale)
3321     {
3322         /* Insert decimal point */
3323         StringBuilder buf;
3324         int insertionPoint = cast(int)(intString.length) - scale;
3325         if (insertionPoint == 0)
3326         { /* Point goes right before intVal */
3327             return (signum < 0 ? "-0." : "0.") ~ intString;
3328         }
3329         else if (insertionPoint > 0)
3330         { /* Point goes inside intVal */
3331             buf = new StringBuilder(intString);
3332             buf.insert(insertionPoint, '.');
3333             if (signum < 0)
3334                 buf.insert(0, '-');
3335         }
3336         else
3337         { /* We must insert zeros between point and intVal */
3338             buf = new StringBuilder(3 - insertionPoint + intString.length);
3339             buf.append(signum < 0 ? "-0." : "0.");
3340             for (int i = 0; i < -insertionPoint; i++)
3341             {
3342                 buf.append('0');
3343             }
3344             buf.append(intString);
3345         }
3346         return buf.toString();
3347     }
3348 
3349     /**
3350      * Converts this {@code BigDecimal} to a {@code BigInteger}.
3351      * This conversion is analogous to the
3352      * <i>narrowing primitive conversion</i> from {@code double} to
3353      * {@code long} as defined in
3354      * <cite>The Java&trade; Language Specification</cite>:
3355      * any fractional part of this
3356      * {@code BigDecimal} will be discarded.  Note that this
3357      * conversion can lose information about the precision of the
3358      * {@code BigDecimal} value.
3359      * <p>
3360      * To have an exception thrown if the conversion is inexact (in
3361      * other words if a nonzero fractional part is discarded), use the
3362      * {@link #toBigIntegerExact()} method.
3363      *
3364      * @return this {@code BigDecimal} converted to a {@code BigInteger}.
3365      * @jls 5.1.3 Narrowing Primitive Conversion
3366      */
3367     BigInteger toBigInteger()
3368     {
3369         // force to an integer, quietly
3370         return this.setScale(0, ROUND_DOWN).inflated();
3371     }
3372 
3373     /**
3374      * Converts this {@code BigDecimal} to a {@code BigInteger},
3375      * checking for lost information.  An exception is thrown if this
3376      * {@code BigDecimal} has a nonzero fractional part.
3377      *
3378      * @return this {@code BigDecimal} converted to a {@code BigInteger}.
3379      * @throws ArithmeticException if {@code this} has a nonzero
3380      *         fractional part.
3381      */    
3382     BigInteger toBigIntegerExact()
3383     {
3384         // round to an integer, with Exception if decimal part non-0
3385         return this.setScale(0, ROUND_UNNECESSARY).inflated();
3386     }
3387 
3388     //     /**
3389     //      * Converts this {@code BigDecimal} to a {@code long}.
3390     //      * This conversion is analogous to the
3391     //      * <i>narrowing primitive conversion</i> from {@code double} to
3392     //      * {@code short} as defined in
3393     //      * <cite>The Java&trade; Language Specification</cite>:
3394     //      * any fractional part of this
3395     //      * {@code BigDecimal} will be discarded, and if the resulting
3396     //      * "{@code BigInteger}" is too big to fit in a
3397     //      * {@code long}, only the low-order 64 bits are returned.
3398     //      * Note that this conversion can lose information about the
3399     //      * overall magnitude and precision of this {@code BigDecimal} value as well
3400     //      * as return a result with the opposite sign.
3401     //      *
3402     //      * @return this {@code BigDecimal} converted to a {@code long}.
3403     //      * @jls 5.1.3 Narrowing Primitive Conversion
3404     //      */
3405     //     @Override
3406     //     long longValue(){
3407     //         return (intCompact != INFLATED && scale == 0) ?
3408     //             intCompact:
3409     //             toBigInteger().longValue();
3410     //     }
3411 
3412     //     /**
3413     //      * Converts this {@code BigDecimal} to a {@code long}, checking
3414     //      * for lost information.  If this {@code BigDecimal} has a
3415     //      * nonzero fractional part or is out of the possible range for a
3416     //      * {@code long} result then an {@code ArithmeticException} is
3417     //      * thrown.
3418     //      *
3419     //      * @return this {@code BigDecimal} converted to a {@code long}.
3420     //      * @throws ArithmeticException if {@code this} has a nonzero
3421     //      *         fractional part, or will not fit in a {@code long}.
3422     //      */
3423     //     long longValueExact() {
3424     //         if (intCompact != INFLATED && scale == 0)
3425     //             return intCompact;
3426     //         // If more than 19 digits in integer part it cannot possibly fit
3427     //         if ((precision() - scale) > 19) // [OK for negative scale too]
3428     //             throw new java.lang.ArithmeticException("Overflow");
3429     //         // Fastpath zero and < 1.0 numbers (the latter can be very slow
3430     //         // to round if very small)
3431     //         if (this.signum() == 0)
3432     //             return 0;
3433     //         if ((this.precision() - this.scale) <= 0)
3434     //             throw new ArithmeticException("Rounding necessary");
3435     //         // round to an integer, with Exception if decimal part non-0
3436     //         BigDecimal num = this.setScale(0, ROUND_UNNECESSARY);
3437     //         if (num.precision() >= 19) // need to check carefully
3438     //             LongOverflow.check(num);
3439     //         return num.inflated().longValue();
3440     //     }
3441 
3442     //     private static class LongOverflow {
3443     //         /** BigInteger equal to Long.MIN_VALUE. */
3444     //         private static final BigInteger LONGMIN = BigInteger.valueOf(Long.MIN_VALUE);
3445 
3446     //         /** BigInteger equal to Long.MAX_VALUE. */
3447     //         private static final BigInteger LONGMAX = BigInteger.valueOf(Long.MAX_VALUE);
3448 
3449     //         static void check(BigDecimal num) {
3450     //             BigInteger intVal = num.inflated();
3451     //             if (intVal.compareTo(LONGMIN) < 0 ||
3452     //                 intVal.compareTo(LONGMAX) > 0)
3453     //                 throw new java.lang.ArithmeticException("Overflow");
3454     //         }
3455     //     }
3456 
3457     //     /**
3458     //      * Converts this {@code BigDecimal} to an {@code int}.
3459     //      * This conversion is analogous to the
3460     //      * <i>narrowing primitive conversion</i> from {@code double} to
3461     //      * {@code short} as defined in
3462     //      * <cite>The Java&trade; Language Specification</cite>:
3463     //      * any fractional part of this
3464     //      * {@code BigDecimal} will be discarded, and if the resulting
3465     //      * "{@code BigInteger}" is too big to fit in an
3466     //      * {@code int}, only the low-order 32 bits are returned.
3467     //      * Note that this conversion can lose information about the
3468     //      * overall magnitude and precision of this {@code BigDecimal}
3469     //      * value as well as return a result with the opposite sign.
3470     //      *
3471     //      * @return this {@code BigDecimal} converted to an {@code int}.
3472     //      * @jls 5.1.3 Narrowing Primitive Conversion
3473     //      */
3474     //     @Override
3475     //     int intValue() {
3476     //         return  (intCompact != INFLATED && scale == 0) ?
3477     //             (int)intCompact :
3478     //             toBigInteger().intValue();
3479     //     }
3480 
3481     //     /**
3482     //      * Converts this {@code BigDecimal} to an {@code int}, checking
3483     //      * for lost information.  If this {@code BigDecimal} has a
3484     //      * nonzero fractional part or is out of the possible range for an
3485     //      * {@code int} result then an {@code ArithmeticException} is
3486     //      * thrown.
3487     //      *
3488     //      * @return this {@code BigDecimal} converted to an {@code int}.
3489     //      * @throws ArithmeticException if {@code this} has a nonzero
3490     //      *         fractional part, or will not fit in an {@code int}.
3491     //      */
3492     //     int intValueExact() {
3493     //        long num;
3494     //        num = this.longValueExact();     // will check decimal part
3495     //        if ((int)num != num)
3496     //            throw new java.lang.ArithmeticException("Overflow");
3497     //        return (int)num;
3498     //     }
3499 
3500     //     /**
3501     //      * Converts this {@code BigDecimal} to a {@code short}, checking
3502     //      * for lost information.  If this {@code BigDecimal} has a
3503     //      * nonzero fractional part or is out of the possible range for a
3504     //      * {@code short} result then an {@code ArithmeticException} is
3505     //      * thrown.
3506     //      *
3507     //      * @return this {@code BigDecimal} converted to a {@code short}.
3508     //      * @throws ArithmeticException if {@code this} has a nonzero
3509     //      *         fractional part, or will not fit in a {@code short}.
3510     //      */
3511     //     short shortValueExact() {
3512     //        long num;
3513     //        num = this.longValueExact();     // will check decimal part
3514     //        if ((short)num != num)
3515     //            throw new java.lang.ArithmeticException("Overflow");
3516     //        return (short)num;
3517     //     }
3518 
3519     //     /**
3520     //      * Converts this {@code BigDecimal} to a {@code byte}, checking
3521     //      * for lost information.  If this {@code BigDecimal} has a
3522     //      * nonzero fractional part or is out of the possible range for a
3523     //      * {@code byte} result then an {@code ArithmeticException} is
3524     //      * thrown.
3525     //      *
3526     //      * @return this {@code BigDecimal} converted to a {@code byte}.
3527     //      * @throws ArithmeticException if {@code this} has a nonzero
3528     //      *         fractional part, or will not fit in a {@code byte}.
3529     //      */
3530     //     byte byteValueExact() {
3531     //        long num;
3532     //        num = this.longValueExact();     // will check decimal part
3533     //        if ((byte)num != num)
3534     //            throw new java.lang.ArithmeticException("Overflow");
3535     //        return (byte)num;
3536     //     }
3537 
3538     //     /**
3539     //      * Converts this {@code BigDecimal} to a {@code float}.
3540     //      * This conversion is similar to the
3541     //      * <i>narrowing primitive conversion</i> from {@code double} to
3542     //      * {@code float} as defined in
3543     //      * <cite>The Java&trade; Language Specification</cite>:
3544     //      * if this {@code BigDecimal} has too great a
3545     //      * magnitude to represent as a {@code float}, it will be
3546     //      * converted to {@link Float#NEGATIVE_INFINITY} or {@link
3547     //      * Float#POSITIVE_INFINITY} as appropriate.  Note that even when
3548     //      * the return value is finite, this conversion can lose
3549     //      * information about the precision of the {@code BigDecimal}
3550     //      * value.
3551     //      *
3552     //      * @return this {@code BigDecimal} converted to a {@code float}.
3553     //      * @jls 5.1.3 Narrowing Primitive Conversion
3554     //      */
3555     //     @Override
3556     //     float floatValue(){
3557     //         if(intCompact != INFLATED) {
3558     //             if (scale == 0) {
3559     //                 return (float)intCompact;
3560     //             } else {
3561     //                 /*
3562     //                  * If both intCompact and the scale can be exactly
3563     //                  * represented as float values, perform a single float
3564     //                  * multiply or divide to compute the (properly
3565     //                  * rounded) result.
3566     //                  */
3567     //                 if (MathHelper.abs(intCompact) < 1L<<22 ) {
3568     //                     // Don't have too guard against
3569     //                     // MathHelper.abs(MIN_VALUE) because of outer check
3570     //                     // against INFLATED.
3571     //                     if (scale > 0 && scale < FLOAT_10_POW.length) {
3572     //                         return (float)intCompact / FLOAT_10_POW[scale];
3573     //                     } else if (scale < 0 && scale > -FLOAT_10_POW.length) {
3574     //                         return (float)intCompact * FLOAT_10_POW[-scale];
3575     //                     }
3576     //                 }
3577     //             }
3578     //         }
3579     //         // Somewhat inefficient, but guaranteed to work.
3580     //         return Float.parseFloat(this.toString());
3581     //     }
3582 
3583     //     /**
3584     //      * Converts this {@code BigDecimal} to a {@code double}.
3585     //      * This conversion is similar to the
3586     //      * <i>narrowing primitive conversion</i> from {@code double} to
3587     //      * {@code float} as defined in
3588     //      * <cite>The Java&trade; Language Specification</cite>:
3589     //      * if this {@code BigDecimal} has too great a
3590     //      * magnitude represent as a {@code double}, it will be
3591     //      * converted to {@link Double#NEGATIVE_INFINITY} or {@link
3592     //      * Double#POSITIVE_INFINITY} as appropriate.  Note that even when
3593     //      * the return value is finite, this conversion can lose
3594     //      * information about the precision of the {@code BigDecimal}
3595     //      * value.
3596     //      *
3597     //      * @return this {@code BigDecimal} converted to a {@code double}.
3598     //      * @jls 5.1.3 Narrowing Primitive Conversion
3599     //      */
3600     //     @Override
3601     //     double doubleValue(){
3602     //         if(intCompact != INFLATED) {
3603     //             if (scale == 0) {
3604     //                 return (double)intCompact;
3605     //             } else {
3606     //                 /*
3607     //                  * If both intCompact and the scale can be exactly
3608     //                  * represented as double values, perform a single
3609     //                  * double multiply or divide to compute the (properly
3610     //                  * rounded) result.
3611     //                  */
3612     //                 if (MathHelper.abs(intCompact) < 1L<<52 ) {
3613     //                     // Don't have too guard against
3614     //                     // MathHelper.abs(MIN_VALUE) because of outer check
3615     //                     // against INFLATED.
3616     //                     if (scale > 0 && scale < DOUBLE_10_POW.length) {
3617     //                         return (double)intCompact / DOUBLE_10_POW[scale];
3618     //                     } else if (scale < 0 && scale > -DOUBLE_10_POW.length) {
3619     //                         return (double)intCompact * DOUBLE_10_POW[-scale];
3620     //                     }
3621     //                 }
3622     //             }
3623     //         }
3624     //         // Somewhat inefficient, but guaranteed to work.
3625     //         return Double.parseDouble(this.toString());
3626     //     }
3627 
3628     //     /**
3629     //      * Powers of 10 which can be represented exactly in {@code
3630     //      * double}.
3631     //      */
3632     //     private static final double DOUBLE_10_POW[] = {
3633     //         1.0e0,  1.0e1,  1.0e2,  1.0e3,  1.0e4,  1.0e5,
3634     //         1.0e6,  1.0e7,  1.0e8,  1.0e9,  1.0e10, 1.0e11,
3635     //         1.0e12, 1.0e13, 1.0e14, 1.0e15, 1.0e16, 1.0e17,
3636     //         1.0e18, 1.0e19, 1.0e20, 1.0e21, 1.0e22
3637     //     };
3638 
3639     //     /**
3640     //      * Powers of 10 which can be represented exactly in {@code
3641     //      * float}.
3642     //      */
3643     //     private static final float FLOAT_10_POW[] = {
3644     //         1.0e0f, 1.0e1f, 1.0e2f, 1.0e3f, 1.0e4f, 1.0e5f,
3645     //         1.0e6f, 1.0e7f, 1.0e8f, 1.0e9f, 1.0e10f
3646     //     };
3647 
3648     //     /**
3649     //      * Returns the size of an ulp, a unit in the last place, of this
3650     //      * {@code BigDecimal}.  An ulp of a nonzero {@code BigDecimal}
3651     //      * value is the positive distance between this value and the
3652     //      * {@code BigDecimal} value next larger in magnitude with the
3653     //      * same number of digits.  An ulp of a zero value is numerically
3654     //      * equal to 1 with the scale of {@code this}.  The result is
3655     //      * stored with the same scale as {@code this} so the result
3656     //      * for zero and nonzero values is equal to {@code [1,
3657     //      * this.scale()]}.
3658     //      *
3659     //      * @return the size of an ulp of {@code this}
3660     //      */
3661     //     BigDecimal ulp() {
3662     //         return BigDecimal.valueOf(1, this.scale(), 1);
3663     //     }
3664 
3665     //     // Private class to build a string representation for BigDecimal object.
3666     //     // "StringBuilderHelper" is constructed as a thread local variable so it is
3667     //     // thread safe. The StringBuilder field acts as a buffer to hold the temporary
3668     //     // representation of BigDecimal. The cmpCharArray holds all the characters for
3669     //     // the compact representation of BigDecimal (except for '-' sign' if it is
3670     //     // negative) if its intCompact field is not INFLATED. It is shared by all
3671     //     // calls to toString() and its variants in that particular thread.
3672     //     static class StringBuilderHelper {
3673     //         final StringBuilder sb;    // Placeholder for BigDecimal string
3674     //         final char[] cmpCharArray; // character array to place the intCompact
3675 
3676     //         StringBuilderHelper() {
3677     //             sb = new StringBuilder();
3678     //             // All non negative longs can be made to fit into 19 character array.
3679     //             cmpCharArray = new char[19];
3680     //         }
3681 
3682     //         // Accessors.
3683     //         StringBuilder getStringBuilder() {
3684     //             sb.setLength(0);
3685     //             return sb;
3686     //         }
3687 
3688     //         char[] getCompactCharArray() {
3689     //             return cmpCharArray;
3690     //         }
3691 
3692     //         /**
3693     //          * Places characters representing the intCompact in {@code long} into
3694     //          * cmpCharArray and returns the offset to the array where the
3695     //          * representation starts.
3696     //          *
3697     //          * @param intCompact the number to put into the cmpCharArray.
3698     //          * @return offset to the array where the representation starts.
3699     //          * Note: intCompact must be greater or equal to zero.
3700     //          */
3701     //         int putIntCompact(long intCompact) {
3702     //             assert intCompact >= 0;
3703 
3704     //             long q;
3705     //             int r;
3706     //             // since we start from the least significant digit, charPos points to
3707     //             // the last character in cmpCharArray.
3708     //             int charPos = cmpCharArray.length;
3709 
3710     //             // Get 2 digits/iteration using longs until quotient fits into an int
3711     //             while (intCompact > Integer.MAX_VALUE) {
3712     //                 q = intCompact / 100;
3713     //                 r = (int)(intCompact - q * 100);
3714     //                 intCompact = q;
3715     //                 cmpCharArray[--charPos] = DIGIT_ONES[r];
3716     //                 cmpCharArray[--charPos] = DIGIT_TENS[r];
3717     //             }
3718 
3719     //             // Get 2 digits/iteration using ints when i2 >= 100
3720     //             int q2;
3721     //             int i2 = (int)intCompact;
3722     //             while (i2 >= 100) {
3723     //                 q2 = i2 / 100;
3724     //                 r  = i2 - q2 * 100;
3725     //                 i2 = q2;
3726     //                 cmpCharArray[--charPos] = DIGIT_ONES[r];
3727     //                 cmpCharArray[--charPos] = DIGIT_TENS[r];
3728     //             }
3729 
3730     //             cmpCharArray[--charPos] = DIGIT_ONES[i2];
3731     //             if (i2 >= 10)
3732     //                 cmpCharArray[--charPos] = DIGIT_TENS[i2];
3733 
3734     //             return charPos;
3735     //         }
3736 
3737     //         static final char[] DIGIT_TENS = {
3738     //             '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
3739     //             '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
3740     //             '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
3741     //             '3', '3', '3', '3', '3', '3', '3', '3', '3', '3',
3742     //             '4', '4', '4', '4', '4', '4', '4', '4', '4', '4',
3743     //             '5', '5', '5', '5', '5', '5', '5', '5', '5', '5',
3744     //             '6', '6', '6', '6', '6', '6', '6', '6', '6', '6',
3745     //             '7', '7', '7', '7', '7', '7', '7', '7', '7', '7',
3746     //             '8', '8', '8', '8', '8', '8', '8', '8', '8', '8',
3747     //             '9', '9', '9', '9', '9', '9', '9', '9', '9', '9',
3748     //         };
3749 
3750     //         static final char[] DIGIT_ONES = {
3751     //             '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
3752     //             '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
3753     //             '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
3754     //             '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
3755     //             '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
3756     //             '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
3757     //             '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
3758     //             '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
3759     //             '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
3760     //             '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
3761     //         };
3762     //     }
3763 
3764     //     /**
3765     //      * Lay out this {@code BigDecimal} into a {@code char[]} array.
3766     //      * The Java 1.2 equivalent to this was called {@code getValueString}.
3767     //      *
3768     //      * @param  sci {@code true} for Scientific exponential notation;
3769     //      *          {@code false} for Engineering
3770     //      * @return string with canonical string representation of this
3771     //      *         {@code BigDecimal}
3772     //      */
3773     //     private string layoutChars(bool sci) {
3774     //         if (scale == 0)                      // zero scale is trivial
3775     //             return (intCompact != INFLATED) ?
3776     //                 Long.toString(intCompact):
3777     //                 intVal.toString();
3778     //         if (scale == 2  &&
3779     //             intCompact >= 0 && intCompact < Integer.MAX_VALUE) {
3780     //             // currency fast path
3781     //             int lowInt = (int)intCompact % 100;
3782     //             int highInt = (int)intCompact / 100;
3783     //             return (Integer.toString(highInt) ~ '.' ~
3784     //                     StringBuilderHelper.DIGIT_TENS[lowInt] +
3785     //                     StringBuilderHelper.DIGIT_ONES[lowInt]) ;
3786     //         }
3787 
3788     //         StringBuilderHelper sbHelper = threadLocalStringBuilderHelper.get();
3789     //         char[] coeff;
3790     //         int offset;  // offset is the starting index for coeff array
3791     //         // Get the significand as an absolute value
3792     //         if (intCompact != INFLATED) {
3793     //             offset = sbHelper.putIntCompact(MathHelper.abs(intCompact));
3794     //             coeff  = sbHelper.getCompactCharArray();
3795     //         } else {
3796     //             offset = 0;
3797     //             coeff  = intVal.abs().toString().toCharArray();
3798     //         }
3799 
3800     //         // Construct a buffer, with sufficient capacity for all cases.
3801     //         // If E-notation is needed, length will be: +1 if negative, +1
3802     //         // if '.' needed, +2 for "E+", + up to 10 for adjusted exponent.
3803     //         // Otherwise it could have +1 if negative, plus leading "0.00000"
3804     //         StringBuilder buf = sbHelper.getStringBuilder();
3805     //         if (signum() < 0)             // prefix '-' if negative
3806     //             buf.append('-');
3807     //         int coeffLen = coeff.length - offset;
3808     //         long adjusted = -(long)scale + (coeffLen -1);
3809     //         if ((scale >= 0) && (adjusted >= -6)) { // plain number
3810     //             int pad = scale - coeffLen;         // count of padding zeros
3811     //             if (pad >= 0) {                     // 0.xxx form
3812     //                 buf.append('0');
3813     //                 buf.append('.');
3814     //                 for (; pad>0; pad--) {
3815     //                     buf.append('0');
3816     //                 }
3817     //                 buf.append(coeff, offset, coeffLen);
3818     //             } else {                         // xx.xx form
3819     //                 buf.append(coeff, offset, -pad);
3820     //                 buf.append('.');
3821     //                 buf.append(coeff, -pad + offset, scale);
3822     //             }
3823     //         } else { // E-notation is needed
3824     //             if (sci) {                       // Scientific notation
3825     //                 buf.append(coeff[offset]);   // first character
3826     //                 if (coeffLen > 1) {          // more to come
3827     //                     buf.append('.');
3828     //                     buf.append(coeff, offset + 1, coeffLen - 1);
3829     //                 }
3830     //             } else {                         // Engineering notation
3831     //                 int sig = (int)(adjusted % 3);
3832     //                 if (sig < 0)
3833     //                     sig += 3;                // [adjusted was negative]
3834     //                 adjusted -= sig;             // now a multiple of 3
3835     //                 sig++;
3836     //                 if (signum() == 0) {
3837     //                     switch (sig) {
3838     //                     case 1:
3839     //                         buf.append('0'); // exponent is a multiple of three
3840     //                         break;
3841     //                     case 2:
3842     //                         buf.append("0.00");
3843     //                         adjusted += 3;
3844     //                         break;
3845     //                     case 3:
3846     //                         buf.append("0.0");
3847     //                         adjusted += 3;
3848     //                         break;
3849     //                     default:
3850     //                         throw new AssertionError("Unexpected sig value " ~ sig);
3851     //                     }
3852     //                 } else if (sig >= coeffLen) {   // significand all in integer
3853     //                     buf.append(coeff, offset, coeffLen);
3854     //                     // may need some zeros, too
3855     //                     for (int i = sig - coeffLen; i > 0; i--) {
3856     //                         buf.append('0');
3857     //                     }
3858     //                 } else {                     // xx.xxE form
3859     //                     buf.append(coeff, offset, sig);
3860     //                     buf.append('.');
3861     //                     buf.append(coeff, offset + sig, coeffLen - sig);
3862     //                 }
3863     //             }
3864     //             if (adjusted != 0) {             // [!sci could have made 0]
3865     //                 buf.append('E');
3866     //                 if (adjusted > 0)            // force sign for positive
3867     //                     buf.append('+');
3868     //                 buf.append(adjusted);
3869     //             }
3870     //         }
3871     //         return buf.toString();
3872     //     }
3873 
3874     //     /**
3875     //      * Return 10 to the power n, as a {@code BigInteger}.
3876     //      *
3877     //      * @param  n the power of ten to be returned (>=0)
3878     //      * @return a {@code BigInteger} with the value (10!(sup)n</sup>)
3879     //      */
3880     //     private static BigInteger bigTenToThe(int n) {
3881     //         if (n < 0)
3882     //             return BigInteger.ZERO;
3883 
3884     //         if (n < BIG_TEN_POWERS_TABLE_MAX) {
3885     //             BigInteger[] pows = BIG_TEN_POWERS_TABLE;
3886     //             if (n < pows.length)
3887     //                 return pows[n];
3888     //             else
3889     //                 return expandBigIntegerTenPowers(n);
3890     //         }
3891 
3892     //         return BigInteger.TEN.pow(n);
3893     //     }
3894 
3895     //     /**
3896     //      * Expand the BIG_TEN_POWERS_TABLE array to contain at least 10**n.
3897     //      *
3898     //      * @param n the power of ten to be returned (>=0)
3899     //      * @return a {@code BigDecimal} with the value (10!(sup)n</sup>) and
3900     //      *         in the meantime, the BIG_TEN_POWERS_TABLE array gets
3901     //      *         expanded to the size greater than n.
3902     //      */
3903     //     private static BigInteger expandBigIntegerTenPowers(int n) {
3904     //         synchronized(BigDecimal.class) {
3905     //             BigInteger[] pows = BIG_TEN_POWERS_TABLE;
3906     //             int curLen = pows.length;
3907     //             // The following comparison and the above synchronized statement is
3908     //             // to prevent multiple threads from expanding the same array.
3909     //             if (curLen <= n) {
3910     //                 int newLen = curLen << 1;
3911     //                 while (newLen <= n) {
3912     //                     newLen <<= 1;
3913     //                 }
3914     //                 pows = Arrays.copyOf(pows, newLen);
3915     //                 for (int i = curLen; i < newLen; i++) {
3916     //                     pows[i] = pows[i - 1].multiply(BigInteger.TEN);
3917     //                 }
3918     //                 // Based on the following facts:
3919     //                 // 1. pows is a private local varible;
3920     //                 // 2. the following store is a store.
3921     //                 // the newly created array elements can be safely published.
3922     //                 BIG_TEN_POWERS_TABLE = pows;
3923     //             }
3924     //             return pows[n];
3925     //         }
3926     //     }
3927 
3928     //     private static final long[] LONG_TEN_POWERS_TABLE = {
3929     //         1,                     // 0 / 10^0
3930     //         10,                    // 1 / 10^1
3931     //         100,                   // 2 / 10^2
3932     //         1000,                  // 3 / 10^3
3933     //         10000,                 // 4 / 10^4
3934     //         100000,                // 5 / 10^5
3935     //         1000000,               // 6 / 10^6
3936     //         10000000,              // 7 / 10^7
3937     //         100000000,             // 8 / 10^8
3938     //         1000000000,            // 9 / 10^9
3939     //         10000000000L,          // 10 / 10^10
3940     //         100000000000L,         // 11 / 10^11
3941     //         1000000000000L,        // 12 / 10^12
3942     //         10000000000000L,       // 13 / 10^13
3943     //         100000000000000L,      // 14 / 10^14
3944     //         1000000000000000L,     // 15 / 10^15
3945     //         10000000000000000L,    // 16 / 10^16
3946     //         100000000000000000L,   // 17 / 10^17
3947     //         1000000000000000000L   // 18 / 10^18
3948     //     };
3949 
3950     //     private static BigInteger BIG_TEN_POWERS_TABLE[] = {
3951     //         BigInteger.ONE,
3952     //         BigInteger.valueOf(10),
3953     //         BigInteger.valueOf(100),
3954     //         BigInteger.valueOf(1000),
3955     //         BigInteger.valueOf(10000),
3956     //         BigInteger.valueOf(100000),
3957     //         BigInteger.valueOf(1000000),
3958     //         BigInteger.valueOf(10000000),
3959     //         BigInteger.valueOf(100000000),
3960     //         BigInteger.valueOf(1000000000),
3961     //         BigInteger.valueOf(10000000000L),
3962     //         BigInteger.valueOf(100000000000L),
3963     //         BigInteger.valueOf(1000000000000L),
3964     //         BigInteger.valueOf(10000000000000L),
3965     //         BigInteger.valueOf(100000000000000L),
3966     //         BigInteger.valueOf(1000000000000000L),
3967     //         BigInteger.valueOf(10000000000000000L),
3968     //         BigInteger.valueOf(100000000000000000L),
3969     //         BigInteger.valueOf(1000000000000000000L)
3970     //     };
3971 
3972     //     private static final int BIG_TEN_POWERS_TABLE_INITLEN =
3973     //         BIG_TEN_POWERS_TABLE.length;
3974     //     private static final int BIG_TEN_POWERS_TABLE_MAX =
3975     //         16 * BIG_TEN_POWERS_TABLE_INITLEN;
3976 
3977     //     private static final long THRESHOLDS_TABLE[] = {
3978     //         Long.MAX_VALUE,                     // 0
3979     //         Long.MAX_VALUE/10L,                 // 1
3980     //         Long.MAX_VALUE/100L,                // 2
3981     //         Long.MAX_VALUE/1000L,               // 3
3982     //         Long.MAX_VALUE/10000L,              // 4
3983     //         Long.MAX_VALUE/100000L,             // 5
3984     //         Long.MAX_VALUE/1000000L,            // 6
3985     //         Long.MAX_VALUE/10000000L,           // 7
3986     //         Long.MAX_VALUE/100000000L,          // 8
3987     //         Long.MAX_VALUE/1000000000L,         // 9
3988     //         Long.MAX_VALUE/10000000000L,        // 10
3989     //         Long.MAX_VALUE/100000000000L,       // 11
3990     //         Long.MAX_VALUE/1000000000000L,      // 12
3991     //         Long.MAX_VALUE/10000000000000L,     // 13
3992     //         Long.MAX_VALUE/100000000000000L,    // 14
3993     //         Long.MAX_VALUE/1000000000000000L,   // 15
3994     //         Long.MAX_VALUE/10000000000000000L,  // 16
3995     //         Long.MAX_VALUE/100000000000000000L, // 17
3996     //         Long.MAX_VALUE/1000000000000000000L // 18
3997     //     };
3998 
3999     //     /**
4000     //      * Compute val * 10 ^ n; return this product if it is
4001     //      * representable as a long, INFLATED otherwise.
4002     //      */
4003     //     private static long longMultiplyPowerTen(long val, int n) {
4004     //         if (val == 0 || n <= 0)
4005     //             return val;
4006     //         long[] tab = LONG_TEN_POWERS_TABLE;
4007     //         long[] bounds = THRESHOLDS_TABLE;
4008     //         if (n < tab.length && n < bounds.length) {
4009     //             long tenpower = tab[n];
4010     //             if (val == 1)
4011     //                 return tenpower;
4012     //             if (MathHelper.abs(val) <= bounds[n])
4013     //                 return val * tenpower;
4014     //         }
4015     //         return INFLATED;
4016     //     }
4017 
4018     //     /**
4019     //      * Compute this * 10 ^ n.
4020     //      * Needed mainly to allow special casing to trap zero value
4021     //      */
4022     //     private BigInteger bigMultiplyPowerTen(int n) {
4023     //         if (n <= 0)
4024     //             return this.inflated();
4025 
4026     //         if (intCompact != INFLATED)
4027     //             return bigTenToThe(n).multiply(intCompact);
4028     //         else
4029     //             return intVal.multiply(bigTenToThe(n));
4030     //     }
4031 
4032     /**
4033      * Returns appropriate BigInteger from intVal field if intVal is
4034      * null, i.e. the compact representation is in use.
4035      */
4036     private BigInteger inflated()
4037     {
4038         if (intVal is null)
4039         {
4040             return BigInteger.valueOf(intCompact);
4041         }
4042         return intVal;
4043     }
4044 
4045     //     /**
4046     //      * Match the scales of two {@code BigDecimal}s to align their
4047     //      * least significant digits.
4048     //      *
4049     //      * <p>If the scales of val[0] and val[1] differ, rescale
4050     //      * (non-destructively) the lower-scaled {@code BigDecimal} so
4051     //      * they match.  That is, the lower-scaled reference will be
4052     //      * replaced by a reference to a new object with the same scale as
4053     //      * the other {@code BigDecimal}.
4054     //      *
4055     //      * @param  val array of two elements referring to the two
4056     //      *         {@code BigDecimal}s to be aligned.
4057     //      */
4058     //     private static void matchScale(BigDecimal[] val) {
4059     //         if (val[0].scale < val[1].scale) {
4060     //             val[0] = val[0].setScale(val[1].scale, ROUND_UNNECESSARY);
4061     //         } else if (val[1].scale < val[0].scale) {
4062     //             val[1] = val[1].setScale(val[0].scale, ROUND_UNNECESSARY);
4063     //         }
4064     //     }
4065 
4066     //     private static class UnsafeHolder {
4067     //         private static final jdk.internal.misc.Unsafe unsafe
4068     //                 = jdk.internal.misc.Unsafe.getUnsafe();
4069     //         private static final long intCompactOffset
4070     //                 = unsafe.objectFieldOffset(BigDecimal.class, "intCompact");
4071     //         private static final long intValOffset
4072     //                 = unsafe.objectFieldOffset(BigDecimal.class, "intVal");
4073 
4074     //         static void setIntCompact(BigDecimal bd, long val) {
4075     //             unsafe.putLong(bd, intCompactOffset, val);
4076     //         }
4077 
4078     //         static void setIntValVolatile(BigDecimal bd, BigInteger val) {
4079     //             unsafe.putObjectVolatile(bd, intValOffset, val);
4080     //         }
4081     //     }
4082 
4083     //     /**
4084     //      * Reconstitute the {@code BigDecimal} instance from a stream (that is,
4085     //      * deserialize it).
4086     //      *
4087     //      * @param s the stream being read.
4088     //      */
4089     //     private void readObject(java.io.ObjectInputStream s)
4090     //         throws java.io.IOException, ClassNotFoundException {
4091     //         // Read in all fields
4092     //         s.defaultReadObject();
4093     //         // validate possibly bad fields
4094     //         if (intVal is null) {
4095     //             string message = "BigDecimal: null intVal in stream";
4096     //             throw new java.io.StreamCorruptedException(message);
4097     //         // [all values of scale are now allowed]
4098     //         }
4099     //         UnsafeHolder.setIntCompact(this, compactValFor(intVal));
4100     //     }
4101 
4102     //    /**
4103     //     * Serialize this {@code BigDecimal} to the stream in question
4104     //     *
4105     //     * @param s the stream to serialize to.
4106     //     */
4107     //    private void writeObject(java.io.ObjectOutputStream s)
4108     //        throws java.io.IOException {
4109     //        // Must inflate to maintain compatible serial form.
4110     //        if (this.intVal is null)
4111     //            UnsafeHolder.setIntValVolatile(this, BigInteger.valueOf(this.intCompact));
4112     //        // Could reset intVal back to null if it has to be set.
4113     //        s.defaultWriteObject();
4114     //    }
4115 
4116     //     /**
4117     //      * Returns the length of the absolute value of a {@code long}, in decimal
4118     //      * digits.
4119     //      *
4120     //      * @param x the {@code long}
4121     //      * @return the length of the unscaled value, in deciaml digits.
4122     //      */
4123     //     static int longDigitLength(long x) {
4124     //         /*
4125     //          * As described in "Bit Twiddling Hacks" by Sean Anderson,
4126     //          * (http://graphics.stanford.edu/~seander/bithacks.html)
4127     //          * integer log 10 of x is within 1 of (1233/4096)* (1 +
4128     //          * integer log 2 of x). The fraction 1233/4096 approximates
4129     //          * log10(2). So we first do a version of log2 (a variant of
4130     //          * Long class with pre-checks and opposite directionality) and
4131     //          * then scale and check against powers table. This is a little
4132     //          * simpler in present context than the version in Hacker's
4133     //          * Delight sec 11-4. Adding one to bit length allows comparing
4134     //          * downward from the LONG_TEN_POWERS_TABLE that we need
4135     //          * anyway.
4136     //          */
4137     //         assert x != BigDecimal.INFLATED;
4138     //         if (x < 0)
4139     //             x = -x;
4140     //         if (x < 10) // must screen for 0, might as well 10
4141     //             return 1;
4142     //         int r = ((64 - Long.numberOfLeadingZeros(x) + 1) * 1233) >>> 12;
4143     //         long[] tab = LONG_TEN_POWERS_TABLE;
4144     //         // if r >= length, must have max possible digits for long
4145     //         return (r >= tab.length || x < tab[r]) ? r : r + 1;
4146     //     }
4147 
4148     //     /**
4149     //      * Returns the length of the absolute value of a BigInteger, in
4150     //      * decimal digits.
4151     //      *
4152     //      * @param b the BigInteger
4153     //      * @return the length of the unscaled value, in decimal digits
4154     //      */
4155     //     private static int bigDigitLength(BigInteger b) {
4156     //         /*
4157     //          * Same idea as the long version, but we need a better
4158     //          * approximation of log10(2). Using 646456993/2^31
4159     //          * is accurate up to max possible reported bitLength.
4160     //          */
4161     //         if (b.signum == 0)
4162     //             return 1;
4163     //         int r = (int)((((long)b.bitLength() + 1) * 646456993) >>> 31);
4164     //         return b.compareMagnitude(bigTenToThe(r)) < 0? r : r+1;
4165     //     }
4166 
4167         /**
4168          * Check a scale for Underflow or Overflow.  If this BigDecimal is
4169          * nonzero, throw an exception if the scale is outof range. If this
4170          * is zero, saturate the scale to the extreme value of the right
4171          * sign if the scale is out of range.
4172          *
4173          * @param val The new scale.
4174          * @throws ArithmeticException (overflow or underflow) if the new
4175          *         scale is out of range.
4176          * @return validated scale as an int.
4177          */
4178     private int checkScale(long val)
4179     {
4180         int asInt = cast(int) val;
4181         if (asInt != val)
4182         {
4183             asInt = val > Integer.MAX_VALUE ? Integer.MAX_VALUE : Integer.MIN_VALUE;
4184             BigInteger b;
4185             if (intCompact != 0 && ((b = intVal) is null || b.signum() != 0))
4186                 throw new ArithmeticException(asInt > 0 ? "Underflow" : "Overflow");
4187         }
4188         return asInt;
4189     }
4190 
4191     //    /**
4192     //      * Returns the compact value for given {@code BigInteger}, or
4193     //      * INFLATED if too big. Relies on internal representation of
4194     //      * {@code BigInteger}.
4195     //      */
4196     //     private static long compactValFor(BigInteger b) {
4197     //         int[] m = b.mag;
4198     //         int len = m.length;
4199     //         if (len == 0)
4200     //             return 0;
4201     //         int d = m[0];
4202     //         if (len > 2 || (len == 2 && d < 0))
4203     //             return INFLATED;
4204 
4205     //         long u = (len == 2)?
4206     //             (((long) m[1] & LONG_MASK) + (((long)d) << 32)) :
4207     //             (((long)d)   & LONG_MASK);
4208     //         return (b.signum < 0)? -u : u;
4209     //     }
4210 
4211     //     private static int longCompareMagnitude(long x, long y) {
4212     //         if (x < 0)
4213     //             x = -x;
4214     //         if (y < 0)
4215     //             y = -y;
4216     //         return (x < y) ? -1 : ((x == y) ? 0 : 1);
4217     //     }
4218 
4219     //     private static int saturateLong(long s) {
4220     //         int i = (int)s;
4221     //         return (s == i) ? i : (s < 0 ? Integer.MIN_VALUE : Integer.MAX_VALUE);
4222     //     }
4223 
4224     //     /*
4225     //      * Internal printing routine
4226     //      */
4227     //     private static void print(string name, BigDecimal bd) {
4228     //         System.err.format("%s:\tintCompact %d\tintVal %d\tscale %d\tprecision %d%n",
4229     //                           name,
4230     //                           bd.intCompact,
4231     //                           bd.intVal,
4232     //                           bd.scale,
4233     //                           bd.precision);
4234     //     }
4235 
4236     //     /**
4237     //      * Check internal invariants of this BigDecimal.  These invariants
4238     //      * include:
4239     //      *
4240     //      * <ul>
4241     //      *
4242     //      * <li>The object must be initialized; either intCompact must not be
4243     //      * INFLATED or intVal is non-null.  Both of these conditions may
4244     //      * be true.
4245     //      *
4246     //      * <li>If both intCompact and intVal and set, their values must be
4247     //      * consistent.
4248     //      *
4249     //      * <li>If precision is nonzero, it must have the right value.
4250     //      * </ul>
4251     //      *
4252     //      * Note: Since this is an audit method, we are not supposed to change the
4253     //      * state of this BigDecimal object.
4254     //      */
4255     //     private BigDecimal audit() {
4256     //         if (intCompact == INFLATED) {
4257     //             if (intVal is null) {
4258     //                 print("audit", this);
4259     //                 throw new AssertionError("null intVal");
4260     //             }
4261     //             // Check precision
4262     //             if (precision > 0 && precision != bigDigitLength(intVal)) {
4263     //                 print("audit", this);
4264     //                 throw new AssertionError("precision mismatch");
4265     //             }
4266     //         } else {
4267     //             if (intVal !is null) {
4268     //                 long val = intVal.longValue();
4269     //                 if (val != intCompact) {
4270     //                     print("audit", this);
4271     //                     throw new AssertionError("Inconsistent state, intCompact=" ~
4272     //                                              intCompact ~ "\t intVal=" ~ val);
4273     //                 }
4274     //             }
4275     //             // Check precision
4276     //             if (precision > 0 && precision != longDigitLength(intCompact)) {
4277     //                 print("audit", this);
4278     //                 throw new AssertionError("precision mismatch");
4279     //             }
4280     //         }
4281     //         return this;
4282     //     }
4283 
4284     /* the same as checkScale where value!=0 */
4285     private static int checkScaleNonZero(long val)
4286     {
4287         int asInt = cast(int) val;
4288         if (asInt != val)
4289         {
4290             throw new ArithmeticException(asInt > 0 ? "Underflow" : "Overflow");
4291         }
4292         return asInt;
4293     }
4294 
4295     //     private static int checkScale(long intCompact, long val) {
4296     //         int asInt = (int)val;
4297     //         if (asInt != val) {
4298     //             asInt = val>Integer.MAX_VALUE ? Integer.MAX_VALUE : Integer.MIN_VALUE;
4299     //             if (intCompact != 0)
4300     //                 throw new ArithmeticException(asInt>0 ? "Underflow":"Overflow");
4301     //         }
4302     //         return asInt;
4303     //     }
4304 
4305     //     private static int checkScale(BigInteger intVal, long val) {
4306     //         int asInt = (int)val;
4307     //         if (asInt != val) {
4308     //             asInt = val>Integer.MAX_VALUE ? Integer.MAX_VALUE : Integer.MIN_VALUE;
4309     //             if (intVal.signum() != 0)
4310     //                 throw new ArithmeticException(asInt>0 ? "Underflow":"Overflow");
4311     //         }
4312     //         return asInt;
4313     //     }
4314 
4315     //     /**
4316     //      * Returns a {@code BigDecimal} rounded according to the MathContext
4317     //      * settings;
4318     //      * If rounding is needed a new {@code BigDecimal} is created and returned.
4319     //      *
4320     //      * @param val the value to be rounded
4321     //      * @param mc the context to use.
4322     //      * @return a {@code BigDecimal} rounded according to the MathContext
4323     //      *         settings.  May return {@code value}, if no rounding needed.
4324     //      * @throws ArithmeticException if the rounding mode is
4325     //      *         {@code RoundingMode.UNNECESSARY} and the
4326     //      *         result is inexact.
4327     //      */
4328     //     private static BigDecimal doRound(BigDecimal val, MathContext mc) {
4329     //         int mcp = mc.precision;
4330     //         bool wasDivided = false;
4331     //         if (mcp > 0) {
4332     //             BigInteger intVal = val.intVal;
4333     //             long compactVal = val.intCompact;
4334     //             int scale = val.scale;
4335     //             int prec = val.precision();
4336     //             int mode = mc.roundingMode.oldMode;
4337     //             int drop;
4338     //             if (compactVal == INFLATED) {
4339     //                 drop = prec - mcp;
4340     //                 while (drop > 0) {
4341     //                     scale = checkScaleNonZero((long) scale - drop);
4342     //                     intVal = divideAndRoundByTenPow(intVal, drop, mode);
4343     //                     wasDivided = true;
4344     //                     compactVal = compactValFor(intVal);
4345     //                     if (compactVal != INFLATED) {
4346     //                         prec = longDigitLength(compactVal);
4347     //                         break;
4348     //                     }
4349     //                     prec = bigDigitLength(intVal);
4350     //                     drop = prec - mcp;
4351     //                 }
4352     //             }
4353     //             if (compactVal != INFLATED) {
4354     //                 drop = prec - mcp;  // drop can't be more than 18
4355     //                 while (drop > 0) {
4356     //                     scale = checkScaleNonZero((long) scale - drop);
4357     //                     compactVal = divideAndRound(compactVal, LONG_TEN_POWERS_TABLE[drop], mc.roundingMode.oldMode);
4358     //                     wasDivided = true;
4359     //                     prec = longDigitLength(compactVal);
4360     //                     drop = prec - mcp;
4361     //                     intVal = null;
4362     //                 }
4363     //             }
4364     //             return wasDivided ? new BigDecimal(intVal,compactVal,scale,prec) : val;
4365     //         }
4366     //         return val;
4367     //     }
4368 
4369     //     /*
4370     //      * Returns a {@code BigDecimal} created from {@code long} value with
4371     //      * given scale rounded according to the MathContext settings
4372     //      */
4373     //     private static BigDecimal doRound(long compactVal, int scale, MathContext mc) {
4374     //         int mcp = mc.precision;
4375     //         if (mcp > 0 && mcp < 19) {
4376     //             int prec = longDigitLength(compactVal);
4377     //             int drop = prec - mcp;  // drop can't be more than 18
4378     //             while (drop > 0) {
4379     //                 scale = checkScaleNonZero((long) scale - drop);
4380     //                 compactVal = divideAndRound(compactVal, LONG_TEN_POWERS_TABLE[drop], mc.roundingMode.oldMode);
4381     //                 prec = longDigitLength(compactVal);
4382     //                 drop = prec - mcp;
4383     //             }
4384     //             return valueOf(compactVal, scale, prec);
4385     //         }
4386     //         return valueOf(compactVal, scale);
4387     //     }
4388 
4389     //     /*
4390     //      * Returns a {@code BigDecimal} created from {@code BigInteger} value with
4391     //      * given scale rounded according to the MathContext settings
4392     //      */
4393     //     private static BigDecimal doRound(BigInteger intVal, int scale, MathContext mc) {
4394     //         int mcp = mc.precision;
4395     //         int prec = 0;
4396     //         if (mcp > 0) {
4397     //             long compactVal = compactValFor(intVal);
4398     //             int mode = mc.roundingMode.oldMode;
4399     //             int drop;
4400     //             if (compactVal == INFLATED) {
4401     //                 prec = bigDigitLength(intVal);
4402     //                 drop = prec - mcp;
4403     //                 while (drop > 0) {
4404     //                     scale = checkScaleNonZero((long) scale - drop);
4405     //                     intVal = divideAndRoundByTenPow(intVal, drop, mode);
4406     //                     compactVal = compactValFor(intVal);
4407     //                     if (compactVal != INFLATED) {
4408     //                         break;
4409     //                     }
4410     //                     prec = bigDigitLength(intVal);
4411     //                     drop = prec - mcp;
4412     //                 }
4413     //             }
4414     //             if (compactVal != INFLATED) {
4415     //                 prec = longDigitLength(compactVal);
4416     //                 drop = prec - mcp;     // drop can't be more than 18
4417     //                 while (drop > 0) {
4418     //                     scale = checkScaleNonZero((long) scale - drop);
4419     //                     compactVal = divideAndRound(compactVal, LONG_TEN_POWERS_TABLE[drop], mc.roundingMode.oldMode);
4420     //                     prec = longDigitLength(compactVal);
4421     //                     drop = prec - mcp;
4422     //                 }
4423     //                 return valueOf(compactVal,scale,prec);
4424     //             }
4425     //         }
4426     //         return new BigDecimal(intVal,INFLATED,scale,prec);
4427     //     }
4428 
4429     //     /*
4430     //      * Divides {@code BigInteger} value by ten power.
4431     //      */
4432     //     private static BigInteger divideAndRoundByTenPow(BigInteger intVal, int tenPow, int roundingMode) {
4433     //         if (tenPow < LONG_TEN_POWERS_TABLE.length)
4434     //             intVal = divideAndRound(intVal, LONG_TEN_POWERS_TABLE[tenPow], roundingMode);
4435     //         else
4436     //             intVal = divideAndRound(intVal, bigTenToThe(tenPow), roundingMode);
4437     //         return intVal;
4438     //     }
4439 
4440     //     /**
4441     //      * Internally used for division operation for division {@code long} by
4442     //      * {@code long}.
4443     //      * The returned {@code BigDecimal} object is the quotient whose scale is set
4444     //      * to the passed in scale. If the remainder is not zero, it will be rounded
4445     //      * based on the passed in roundingMode. Also, if the remainder is zero and
4446     //      * the last parameter, i.e. preferredScale is NOT equal to scale, the
4447     //      * trailing zeros of the result is stripped to match the preferredScale.
4448     //      */
4449     //     private static BigDecimal divideAndRound(long ldividend, long ldivisor, int scale, int roundingMode,
4450     //                                              int preferredScale) {
4451 
4452     //         int qsign; // quotient sign
4453     //         long q = ldividend / ldivisor; // store quotient in long
4454     //         if (roundingMode == ROUND_DOWN && scale == preferredScale)
4455     //             return valueOf(q, scale);
4456     //         long r = ldividend % ldivisor; // store remainder in long
4457     //         qsign = ((ldividend < 0) == (ldivisor < 0)) ? 1 : -1;
4458     //         if (r != 0) {
4459     //             bool increment = needIncrement(ldivisor, roundingMode, qsign, q, r);
4460     //             return valueOf((increment ? q + qsign : q), scale);
4461     //         } else {
4462     //             if (preferredScale != scale)
4463     //                 return createAndStripZerosToMatchScale(q, scale, preferredScale);
4464     //             else
4465     //                 return valueOf(q, scale);
4466     //         }
4467     //     }
4468 
4469     //     /**
4470     //      * Divides {@code long} by {@code long} and do rounding based on the
4471     //      * passed in roundingMode.
4472     //      */
4473     //     private static long divideAndRound(long ldividend, long ldivisor, int roundingMode) {
4474     //         int qsign; // quotient sign
4475     //         long q = ldividend / ldivisor; // store quotient in long
4476     //         if (roundingMode == ROUND_DOWN)
4477     //             return q;
4478     //         long r = ldividend % ldivisor; // store remainder in long
4479     //         qsign = ((ldividend < 0) == (ldivisor < 0)) ? 1 : -1;
4480     //         if (r != 0) {
4481     //             bool increment = needIncrement(ldivisor, roundingMode, qsign, q,     r);
4482     //             return increment ? q + qsign : q;
4483     //         } else {
4484     //             return q;
4485     //         }
4486     //     }
4487 
4488     //     /**
4489     //      * Shared logic of need increment computation.
4490     //      */
4491     //     private static bool commonNeedIncrement(int roundingMode, int qsign,
4492     //                                         int cmpFracHalf, bool oddQuot) {
4493     //         switch(roundingMode) {
4494     //         case ROUND_UNNECESSARY:
4495     //             throw new ArithmeticException("Rounding necessary");
4496 
4497     //         case ROUND_UP: // Away from zero
4498     //             return true;
4499 
4500     //         case ROUND_DOWN: // Towards zero
4501     //             return false;
4502 
4503     //         case ROUND_CEILING: // Towards +infinity
4504     //             return qsign > 0;
4505 
4506     //         case ROUND_FLOOR: // Towards -infinity
4507     //             return qsign < 0;
4508 
4509     //         default: // Some kind of half-way rounding
4510     //             assert roundingMode >= ROUND_HALF_UP &&
4511     //                 roundingMode <= ROUND_HALF_EVEN: "Unexpected rounding mode" ~ RoundingMode.valueOf(roundingMode);
4512 
4513     //             if (cmpFracHalf < 0 ) // We're closer to higher digit
4514     //                 return false;
4515     //             else if (cmpFracHalf > 0 ) // We're closer to lower digit
4516     //                 return true;
4517     //             else { // half-way
4518     //                 assert cmpFracHalf == 0;
4519 
4520     //                 switch(roundingMode) {
4521     //                 case ROUND_HALF_DOWN:
4522     //                     return false;
4523 
4524     //                 case ROUND_HALF_UP:
4525     //                     return true;
4526 
4527     //                 case ROUND_HALF_EVEN:
4528     //                     return oddQuot;
4529 
4530     //                 default:
4531     //                     throw new AssertionError("Unexpected rounding mode" ~ roundingMode);
4532     //                 }
4533     //             }
4534     //         }
4535     //     }
4536 
4537     //     /**
4538     //      * Tests if quotient has to be incremented according the roundingMode
4539     //      */
4540     //     private static bool needIncrement(long ldivisor, int roundingMode,
4541     //                                          int qsign, long q, long r) {
4542     //         assert r != 0L;
4543 
4544     //         int cmpFracHalf;
4545     //         if (r <= HALF_LONG_MIN_VALUE || r > HALF_LONG_MAX_VALUE) {
4546     //             cmpFracHalf = 1; // 2 * r can't fit into long
4547     //         } else {
4548     //             cmpFracHalf = longCompareMagnitude(2 * r, ldivisor);
4549     //         }
4550 
4551     //         return commonNeedIncrement(roundingMode, qsign, cmpFracHalf, (q & 1L) != 0L);
4552     //     }
4553 
4554     //     /**
4555     //      * Divides {@code BigInteger} value by {@code long} value and
4556     //      * do rounding based on the passed in roundingMode.
4557     //      */
4558     //     private static BigInteger divideAndRound(BigInteger bdividend, long ldivisor, int roundingMode) {
4559     //         // Descend into mutables for faster remainder checks
4560     //         MutableBigInteger mdividend = new MutableBigInteger(bdividend.mag);
4561     //         // store quotient
4562     //         MutableBigInteger mq = new MutableBigInteger();
4563     //         // store quotient & remainder in long
4564     //         long r = mdividend.divide(ldivisor, mq);
4565     //         // record remainder is zero or not
4566     //         bool isRemainderZero = (r == 0);
4567     //         // quotient sign
4568     //         int qsign = (ldivisor < 0) ? -bdividend.signum : bdividend.signum;
4569     //         if (!isRemainderZero) {
4570     //             if(needIncrement(ldivisor, roundingMode, qsign, mq, r)) {
4571     //                 mq.add(MutableBigInteger.ONE);
4572     //             }
4573     //         }
4574     //         return mq.toBigInteger(qsign);
4575     //     }
4576 
4577     //     /**
4578     //      * Internally used for division operation for division {@code BigInteger}
4579     //      * by {@code long}.
4580     //      * The returned {@code BigDecimal} object is the quotient whose scale is set
4581     //      * to the passed in scale. If the remainder is not zero, it will be rounded
4582     //      * based on the passed in roundingMode. Also, if the remainder is zero and
4583     //      * the last parameter, i.e. preferredScale is NOT equal to scale, the
4584     //      * trailing zeros of the result is stripped to match the preferredScale.
4585     //      */
4586     //     private static BigDecimal divideAndRound(BigInteger bdividend,
4587     //                                              long ldivisor, int scale, int roundingMode, int preferredScale) {
4588     //         // Descend into mutables for faster remainder checks
4589     //         MutableBigInteger mdividend = new MutableBigInteger(bdividend.mag);
4590     //         // store quotient
4591     //         MutableBigInteger mq = new MutableBigInteger();
4592     //         // store quotient & remainder in long
4593     //         long r = mdividend.divide(ldivisor, mq);
4594     //         // record remainder is zero or not
4595     //         bool isRemainderZero = (r == 0);
4596     //         // quotient sign
4597     //         int qsign = (ldivisor < 0) ? -bdividend.signum : bdividend.signum;
4598     //         if (!isRemainderZero) {
4599     //             if(needIncrement(ldivisor, roundingMode, qsign, mq, r)) {
4600     //                 mq.add(MutableBigInteger.ONE);
4601     //             }
4602     //             return mq.toBigDecimal(qsign, scale);
4603     //         } else {
4604     //             if (preferredScale != scale) {
4605     //                 long compactVal = mq.toCompactValue(qsign);
4606     //                 if(compactVal!=INFLATED) {
4607     //                     return createAndStripZerosToMatchScale(compactVal, scale, preferredScale);
4608     //                 }
4609     //                 BigInteger intVal =  mq.toBigInteger(qsign);
4610     //                 return createAndStripZerosToMatchScale(intVal,scale, preferredScale);
4611     //             } else {
4612     //                 return mq.toBigDecimal(qsign, scale);
4613     //             }
4614     //         }
4615     //     }
4616 
4617     //     /**
4618     //      * Tests if quotient has to be incremented according the roundingMode
4619     //      */
4620     //     private static bool needIncrement(long ldivisor, int roundingMode,
4621     //                                          int qsign, MutableBigInteger mq, long r) {
4622     //         assert r != 0L;
4623 
4624     //         int cmpFracHalf;
4625     //         if (r <= HALF_LONG_MIN_VALUE || r > HALF_LONG_MAX_VALUE) {
4626     //             cmpFracHalf = 1; // 2 * r can't fit into long
4627     //         } else {
4628     //             cmpFracHalf = longCompareMagnitude(2 * r, ldivisor);
4629     //         }
4630 
4631     //         return commonNeedIncrement(roundingMode, qsign, cmpFracHalf, mq.isOdd());
4632     //     }
4633 
4634     //     /**
4635     //      * Divides {@code BigInteger} value by {@code BigInteger} value and
4636     //      * do rounding based on the passed in roundingMode.
4637     //      */
4638     //     private static BigInteger divideAndRound(BigInteger bdividend, BigInteger bdivisor, int roundingMode) {
4639     //         bool isRemainderZero; // record remainder is zero or not
4640     //         int qsign; // quotient sign
4641     //         // Descend into mutables for faster remainder checks
4642     //         MutableBigInteger mdividend = new MutableBigInteger(bdividend.mag);
4643     //         MutableBigInteger mq = new MutableBigInteger();
4644     //         MutableBigInteger mdivisor = new MutableBigInteger(bdivisor.mag);
4645     //         MutableBigInteger mr = mdividend.divide(mdivisor, mq);
4646     //         isRemainderZero = mr.isZero();
4647     //         qsign = (bdividend.signum != bdivisor.signum) ? -1 : 1;
4648     //         if (!isRemainderZero) {
4649     //             if (needIncrement(mdivisor, roundingMode, qsign, mq, mr)) {
4650     //                 mq.add(MutableBigInteger.ONE);
4651     //             }
4652     //         }
4653     //         return mq.toBigInteger(qsign);
4654     //     }
4655 
4656     //     /**
4657     //      * Internally used for division operation for division {@code BigInteger}
4658     //      * by {@code BigInteger}.
4659     //      * The returned {@code BigDecimal} object is the quotient whose scale is set
4660     //      * to the passed in scale. If the remainder is not zero, it will be rounded
4661     //      * based on the passed in roundingMode. Also, if the remainder is zero and
4662     //      * the last parameter, i.e. preferredScale is NOT equal to scale, the
4663     //      * trailing zeros of the result is stripped to match the preferredScale.
4664     //      */
4665     //     private static BigDecimal divideAndRound(BigInteger bdividend, BigInteger bdivisor, int scale, int roundingMode,
4666     //                                              int preferredScale) {
4667     //         bool isRemainderZero; // record remainder is zero or not
4668     //         int qsign; // quotient sign
4669     //         // Descend into mutables for faster remainder checks
4670     //         MutableBigInteger mdividend = new MutableBigInteger(bdividend.mag);
4671     //         MutableBigInteger mq = new MutableBigInteger();
4672     //         MutableBigInteger mdivisor = new MutableBigInteger(bdivisor.mag);
4673     //         MutableBigInteger mr = mdividend.divide(mdivisor, mq);
4674     //         isRemainderZero = mr.isZero();
4675     //         qsign = (bdividend.signum != bdivisor.signum) ? -1 : 1;
4676     //         if (!isRemainderZero) {
4677     //             if (needIncrement(mdivisor, roundingMode, qsign, mq, mr)) {
4678     //                 mq.add(MutableBigInteger.ONE);
4679     //             }
4680     //             return mq.toBigDecimal(qsign, scale);
4681     //         } else {
4682     //             if (preferredScale != scale) {
4683     //                 long compactVal = mq.toCompactValue(qsign);
4684     //                 if (compactVal != INFLATED) {
4685     //                     return createAndStripZerosToMatchScale(compactVal, scale, preferredScale);
4686     //                 }
4687     //                 BigInteger intVal = mq.toBigInteger(qsign);
4688     //                 return createAndStripZerosToMatchScale(intVal, scale, preferredScale);
4689     //             } else {
4690     //                 return mq.toBigDecimal(qsign, scale);
4691     //             }
4692     //         }
4693     //     }
4694 
4695     //     /**
4696     //      * Tests if quotient has to be incremented according the roundingMode
4697     //      */
4698     //     private static bool needIncrement(MutableBigInteger mdivisor, int roundingMode,
4699     //                                          int qsign, MutableBigInteger mq, MutableBigInteger mr) {
4700     //         assert !mr.isZero();
4701     //         int cmpFracHalf = mr.compareHalf(mdivisor);
4702     //         return commonNeedIncrement(roundingMode, qsign, cmpFracHalf, mq.isOdd());
4703     //     }
4704 
4705     //     /**
4706     //      * Remove insignificant trailing zeros from this
4707     //      * {@code BigInteger} value until the preferred scale is reached or no
4708     //      * more zeros can be removed.  If the preferred scale is less than
4709     //      * Integer.MIN_VALUE, all the trailing zeros will be removed.
4710     //      *
4711     //      * @return new {@code BigDecimal} with a scale possibly reduced
4712     //      * to be closed to the preferred scale.
4713     //      */
4714     //     private static BigDecimal createAndStripZerosToMatchScale(BigInteger intVal, int scale, long preferredScale) {
4715     //         BigInteger qr[]; // quotient-remainder pair
4716     //         while (intVal.compareMagnitude(BigInteger.TEN) >= 0
4717     //                && scale > preferredScale) {
4718     //             if (intVal.testBit(0))
4719     //                 break; // odd number cannot end in 0
4720     //             qr = intVal.divideAndRemainder(BigInteger.TEN);
4721     //             if (qr[1].signum() != 0)
4722     //                 break; // non-0 remainder
4723     //             intVal = qr[0];
4724     //             scale = checkScale(intVal,(long) scale - 1); // could Overflow
4725     //         }
4726     //         return valueOf(intVal, scale, 0);
4727     //     }
4728 
4729     //     /**
4730     //      * Remove insignificant trailing zeros from this
4731     //      * {@code long} value until the preferred scale is reached or no
4732     //      * more zeros can be removed.  If the preferred scale is less than
4733     //      * Integer.MIN_VALUE, all the trailing zeros will be removed.
4734     //      *
4735     //      * @return new {@code BigDecimal} with a scale possibly reduced
4736     //      * to be closed to the preferred scale.
4737     //      */
4738     //     private static BigDecimal createAndStripZerosToMatchScale(long compactVal, int scale, long preferredScale) {
4739     //         while (MathHelper.abs(compactVal) >= 10L && scale > preferredScale) {
4740     //             if ((compactVal & 1L) != 0L)
4741     //                 break; // odd number cannot end in 0
4742     //             long r = compactVal % 10L;
4743     //             if (r != 0L)
4744     //                 break; // non-0 remainder
4745     //             compactVal /= 10;
4746     //             scale = checkScale(compactVal, (long) scale - 1); // could Overflow
4747     //         }
4748     //         return valueOf(compactVal, scale);
4749     //     }
4750 
4751     //     private static BigDecimal stripZerosToMatchScale(BigInteger intVal, long intCompact, int scale, int preferredScale) {
4752     //         if(intCompact!=INFLATED) {
4753     //             return createAndStripZerosToMatchScale(intCompact, scale, preferredScale);
4754     //         } else {
4755     //             return createAndStripZerosToMatchScale(intVal==null ? INFLATED_BIGINT : intVal,
4756     //                                                    scale, preferredScale);
4757     //         }
4758     //     }
4759 
4760     //     /*
4761     //      * returns INFLATED if oveflow
4762     //      */
4763     //     private static long add(long xs, long ys){
4764     //         long sum = xs + ys;
4765     //         // See "Hacker's Delight" section 2-12 for explanation of
4766     //         // the overflow test.
4767     //         if ( (((sum ^ xs) & (sum ^ ys))) >= 0L) { // not overflowed
4768     //             return sum;
4769     //         }
4770     //         return INFLATED;
4771     //     }
4772 
4773     //     private static BigDecimal add(long xs, long ys, int scale){
4774     //         long sum = add(xs, ys);
4775     //         if (sum!=INFLATED)
4776     //             return BigDecimal.valueOf(sum, scale);
4777     //         return new BigDecimal(BigInteger.valueOf(xs).add(ys), scale);
4778     //     }
4779 
4780     //     private static BigDecimal add(final long xs, int scale1, final long ys, int scale2) {
4781     //         long sdiff = (long) scale1 - scale2;
4782     //         if (sdiff == 0) {
4783     //             return add(xs, ys, scale1);
4784     //         } else if (sdiff < 0) {
4785     //             int raise = checkScale(xs,-sdiff);
4786     //             long scaledX = longMultiplyPowerTen(xs, raise);
4787     //             if (scaledX != INFLATED) {
4788     //                 return add(scaledX, ys, scale2);
4789     //             } else {
4790     //                 BigInteger bigsum = bigMultiplyPowerTen(xs,raise).add(ys);
4791     //                 return ((xs^ys)>=0) ? // same sign test
4792     //                     new BigDecimal(bigsum, INFLATED, scale2, 0)
4793     //                     : valueOf(bigsum, scale2, 0);
4794     //             }
4795     //         } else {
4796     //             int raise = checkScale(ys,sdiff);
4797     //             long scaledY = longMultiplyPowerTen(ys, raise);
4798     //             if (scaledY != INFLATED) {
4799     //                 return add(xs, scaledY, scale1);
4800     //             } else {
4801     //                 BigInteger bigsum = bigMultiplyPowerTen(ys,raise).add(xs);
4802     //                 return ((xs^ys)>=0) ?
4803     //                     new BigDecimal(bigsum, INFLATED, scale1, 0)
4804     //                     : valueOf(bigsum, scale1, 0);
4805     //             }
4806     //         }
4807     //     }
4808 
4809     //     private static BigDecimal add(final long xs, int scale1, BigInteger snd, int scale2) {
4810     //         int rscale = scale1;
4811     //         long sdiff = (long)rscale - scale2;
4812     //         bool sameSigns =  (Long.signum(xs) == snd.signum);
4813     //         BigInteger sum;
4814     //         if (sdiff < 0) {
4815     //             int raise = checkScale(xs,-sdiff);
4816     //             rscale = scale2;
4817     //             long scaledX = longMultiplyPowerTen(xs, raise);
4818     //             if (scaledX == INFLATED) {
4819     //                 sum = snd.add(bigMultiplyPowerTen(xs,raise));
4820     //             } else {
4821     //                 sum = snd.add(scaledX);
4822     //             }
4823     //         } else { //if (sdiff > 0) {
4824     //             int raise = checkScale(snd,sdiff);
4825     //             snd = bigMultiplyPowerTen(snd,raise);
4826     //             sum = snd.add(xs);
4827     //         }
4828     //         return (sameSigns) ?
4829     //             new BigDecimal(sum, INFLATED, rscale, 0) :
4830     //             valueOf(sum, rscale, 0);
4831     //     }
4832 
4833     //     private static BigDecimal add(BigInteger fst, int scale1, BigInteger snd, int scale2) {
4834     //         int rscale = scale1;
4835     //         long sdiff = (long)rscale - scale2;
4836     //         if (sdiff != 0) {
4837     //             if (sdiff < 0) {
4838     //                 int raise = checkScale(fst,-sdiff);
4839     //                 rscale = scale2;
4840     //                 fst = bigMultiplyPowerTen(fst,raise);
4841     //             } else {
4842     //                 int raise = checkScale(snd,sdiff);
4843     //                 snd = bigMultiplyPowerTen(snd,raise);
4844     //             }
4845     //         }
4846     //         BigInteger sum = fst.add(snd);
4847     //         return (fst.signum == snd.signum) ?
4848     //                 new BigDecimal(sum, INFLATED, rscale, 0) :
4849     //                 valueOf(sum, rscale, 0);
4850     //     }
4851 
4852     //     private static BigInteger bigMultiplyPowerTen(long value, int n) {
4853     //         if (n <= 0)
4854     //             return BigInteger.valueOf(value);
4855     //         return bigTenToThe(n).multiply(value);
4856     //     }
4857 
4858     //     private static BigInteger bigMultiplyPowerTen(BigInteger value, int n) {
4859     //         if (n <= 0)
4860     //             return value;
4861     //         if(n<LONG_TEN_POWERS_TABLE.length) {
4862     //                 return value.multiply(LONG_TEN_POWERS_TABLE[n]);
4863     //         }
4864     //         return value.multiply(bigTenToThe(n));
4865     //     }
4866 
4867     //     /**
4868     //      * Returns a {@code BigDecimal} whose value is {@code (xs /
4869     //      * ys)}, with rounding according to the context settings.
4870     //      *
4871     //      * Fast path - used only when (xscale <= yscale && yscale < 18
4872     //      *  && mc.presision<18) {
4873     //      */
4874     //     private static BigDecimal divideSmallFastPath(final long xs, int xscale,
4875     //                                                   final long ys, int yscale,
4876     //                                                   long preferredScale, MathContext mc) {
4877     //         int mcp = mc.precision;
4878     //         int roundingMode = mc.roundingMode.oldMode;
4879 
4880     //         assert (xscale <= yscale) && (yscale < 18) && (mcp < 18);
4881     //         int xraise = yscale - xscale; // xraise >=0
4882     //         long scaledX = (xraise==0) ? xs :
4883     //             longMultiplyPowerTen(xs, xraise); // can't overflow here!
4884     //         BigDecimal quotient;
4885 
4886     //         int cmp = longCompareMagnitude(scaledX, ys);
4887     //         if(cmp > 0) { // satisfy constraint (b)
4888     //             yscale -= 1; // [that is, divisor *= 10]
4889     //             int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp);
4890     //             if (checkScaleNonZero((long) mcp + yscale - xscale) > 0) {
4891     //                 // assert newScale >= xscale
4892     //                 int raise = checkScaleNonZero((long) mcp + yscale - xscale);
4893     //                 long scaledXs;
4894     //                 if ((scaledXs = longMultiplyPowerTen(xs, raise)) == INFLATED) {
4895     //                     quotient = null;
4896     //                     if((mcp-1) >=0 && (mcp-1)<LONG_TEN_POWERS_TABLE.length) {
4897     //                         quotient = multiplyDivideAndRound(LONG_TEN_POWERS_TABLE[mcp-1], scaledX, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
4898     //                     }
4899     //                     if(quotient==null) {
4900     //                         BigInteger rb = bigMultiplyPowerTen(scaledX,mcp-1);
4901     //                         quotient = divideAndRound(rb, ys,
4902     //                                                   scl, roundingMode, checkScaleNonZero(preferredScale));
4903     //                     }
4904     //                 } else {
4905     //                     quotient = divideAndRound(scaledXs, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
4906     //                 }
4907     //             } else {
4908     //                 int newScale = checkScaleNonZero((long) xscale - mcp);
4909     //                 // assert newScale >= yscale
4910     //                 if (newScale == yscale) { // easy case
4911     //                     quotient = divideAndRound(xs, ys, scl, roundingMode,checkScaleNonZero(preferredScale));
4912     //                 } else {
4913     //                     int raise = checkScaleNonZero((long) newScale - yscale);
4914     //                     long scaledYs;
4915     //                     if ((scaledYs = longMultiplyPowerTen(ys, raise)) == INFLATED) {
4916     //                         BigInteger rb = bigMultiplyPowerTen(ys,raise);
4917     //                         quotient = divideAndRound(BigInteger.valueOf(xs),
4918     //                                                   rb, scl, roundingMode,checkScaleNonZero(preferredScale));
4919     //                     } else {
4920     //                         quotient = divideAndRound(xs, scaledYs, scl, roundingMode,checkScaleNonZero(preferredScale));
4921     //                     }
4922     //                 }
4923     //             }
4924     //         } else {
4925     //             // abs(scaledX) <= abs(ys)
4926     //             // result is "scaledX * 10^msp / ys"
4927     //             int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp);
4928     //             if(cmp==0) {
4929     //                 // abs(scaleX)== abs(ys) => result will be scaled 10^mcp + correct sign
4930     //                 quotient = roundedTenPower(((scaledX < 0) == (ys < 0)) ? 1 : -1, mcp, scl, checkScaleNonZero(preferredScale));
4931     //             } else {
4932     //                 // abs(scaledX) < abs(ys)
4933     //                 long scaledXs;
4934     //                 if ((scaledXs = longMultiplyPowerTen(scaledX, mcp)) == INFLATED) {
4935     //                     quotient = null;
4936     //                     if(mcp<LONG_TEN_POWERS_TABLE.length) {
4937     //                         quotient = multiplyDivideAndRound(LONG_TEN_POWERS_TABLE[mcp], scaledX, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
4938     //                     }
4939     //                     if(quotient==null) {
4940     //                         BigInteger rb = bigMultiplyPowerTen(scaledX,mcp);
4941     //                         quotient = divideAndRound(rb, ys,
4942     //                                                   scl, roundingMode, checkScaleNonZero(preferredScale));
4943     //                     }
4944     //                 } else {
4945     //                     quotient = divideAndRound(scaledXs, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
4946     //                 }
4947     //             }
4948     //         }
4949     //         // doRound, here, only affects 1000000000 case.
4950     //         return doRound(quotient,mc);
4951     //     }
4952 
4953     //     /**
4954     //      * Returns a {@code BigDecimal} whose value is {@code (xs /
4955     //      * ys)}, with rounding according to the context settings.
4956     //      */
4957     //     private static BigDecimal divide(final long xs, int xscale, final long ys, int yscale, long preferredScale, MathContext mc) {
4958     //         int mcp = mc.precision;
4959     //         if(xscale <= yscale && yscale < 18 && mcp<18) {
4960     //             return divideSmallFastPath(xs, xscale, ys, yscale, preferredScale, mc);
4961     //         }
4962     //         if (compareMagnitudeNormalized(xs, xscale, ys, yscale) > 0) {// satisfy constraint (b)
4963     //             yscale -= 1; // [that is, divisor *= 10]
4964     //         }
4965     //         int roundingMode = mc.roundingMode.oldMode;
4966     //         // In order to find out whether the divide generates the exact result,
4967     //         // we avoid calling the above divide method. 'quotient' holds the
4968     //         // return BigDecimal object whose scale will be set to 'scl'.
4969     //         int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp);
4970     //         BigDecimal quotient;
4971     //         if (checkScaleNonZero((long) mcp + yscale - xscale) > 0) {
4972     //             int raise = checkScaleNonZero((long) mcp + yscale - xscale);
4973     //             long scaledXs;
4974     //             if ((scaledXs = longMultiplyPowerTen(xs, raise)) == INFLATED) {
4975     //                 BigInteger rb = bigMultiplyPowerTen(xs,raise);
4976     //                 quotient = divideAndRound(rb, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
4977     //             } else {
4978     //                 quotient = divideAndRound(scaledXs, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
4979     //             }
4980     //         } else {
4981     //             int newScale = checkScaleNonZero((long) xscale - mcp);
4982     //             // assert newScale >= yscale
4983     //             if (newScale == yscale) { // easy case
4984     //                 quotient = divideAndRound(xs, ys, scl, roundingMode,checkScaleNonZero(preferredScale));
4985     //             } else {
4986     //                 int raise = checkScaleNonZero((long) newScale - yscale);
4987     //                 long scaledYs;
4988     //                 if ((scaledYs = longMultiplyPowerTen(ys, raise)) == INFLATED) {
4989     //                     BigInteger rb = bigMultiplyPowerTen(ys,raise);
4990     //                     quotient = divideAndRound(BigInteger.valueOf(xs),
4991     //                                               rb, scl, roundingMode,checkScaleNonZero(preferredScale));
4992     //                 } else {
4993     //                     quotient = divideAndRound(xs, scaledYs, scl, roundingMode,checkScaleNonZero(preferredScale));
4994     //                 }
4995     //             }
4996     //         }
4997     //         // doRound, here, only affects 1000000000 case.
4998     //         return doRound(quotient,mc);
4999     //     }
5000 
5001     //     /**
5002     //      * Returns a {@code BigDecimal} whose value is {@code (xs /
5003     //      * ys)}, with rounding according to the context settings.
5004     //      */
5005     //     private static BigDecimal divide(BigInteger xs, int xscale, long ys, int yscale, long preferredScale, MathContext mc) {
5006     //         // Normalize dividend & divisor so that both fall into [0.1, 0.999...]
5007     //         if ((-compareMagnitudeNormalized(ys, yscale, xs, xscale)) > 0) {// satisfy constraint (b)
5008     //             yscale -= 1; // [that is, divisor *= 10]
5009     //         }
5010     //         int mcp = mc.precision;
5011     //         int roundingMode = mc.roundingMode.oldMode;
5012 
5013     //         // In order to find out whether the divide generates the exact result,
5014     //         // we avoid calling the above divide method. 'quotient' holds the
5015     //         // return BigDecimal object whose scale will be set to 'scl'.
5016     //         BigDecimal quotient;
5017     //         int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp);
5018     //         if (checkScaleNonZero((long) mcp + yscale - xscale) > 0) {
5019     //             int raise = checkScaleNonZero((long) mcp + yscale - xscale);
5020     //             BigInteger rb = bigMultiplyPowerTen(xs,raise);
5021     //             quotient = divideAndRound(rb, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
5022     //         } else {
5023     //             int newScale = checkScaleNonZero((long) xscale - mcp);
5024     //             // assert newScale >= yscale
5025     //             if (newScale == yscale) { // easy case
5026     //                 quotient = divideAndRound(xs, ys, scl, roundingMode,checkScaleNonZero(preferredScale));
5027     //             } else {
5028     //                 int raise = checkScaleNonZero((long) newScale - yscale);
5029     //                 long scaledYs;
5030     //                 if ((scaledYs = longMultiplyPowerTen(ys, raise)) == INFLATED) {
5031     //                     BigInteger rb = bigMultiplyPowerTen(ys,raise);
5032     //                     quotient = divideAndRound(xs, rb, scl, roundingMode,checkScaleNonZero(preferredScale));
5033     //                 } else {
5034     //                     quotient = divideAndRound(xs, scaledYs, scl, roundingMode,checkScaleNonZero(preferredScale));
5035     //                 }
5036     //             }
5037     //         }
5038     //         // doRound, here, only affects 1000000000 case.
5039     //         return doRound(quotient, mc);
5040     //     }
5041 
5042     //     /**
5043     //      * Returns a {@code BigDecimal} whose value is {@code (xs /
5044     //      * ys)}, with rounding according to the context settings.
5045     //      */
5046     //     private static BigDecimal divide(long xs, int xscale, BigInteger ys, int yscale, long preferredScale, MathContext mc) {
5047     //         // Normalize dividend & divisor so that both fall into [0.1, 0.999...]
5048     //         if (compareMagnitudeNormalized(xs, xscale, ys, yscale) > 0) {// satisfy constraint (b)
5049     //             yscale -= 1; // [that is, divisor *= 10]
5050     //         }
5051     //         int mcp = mc.precision;
5052     //         int roundingMode = mc.roundingMode.oldMode;
5053 
5054     //         // In order to find out whether the divide generates the exact result,
5055     //         // we avoid calling the above divide method. 'quotient' holds the
5056     //         // return BigDecimal object whose scale will be set to 'scl'.
5057     //         BigDecimal quotient;
5058     //         int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp);
5059     //         if (checkScaleNonZero((long) mcp + yscale - xscale) > 0) {
5060     //             int raise = checkScaleNonZero((long) mcp + yscale - xscale);
5061     //             BigInteger rb = bigMultiplyPowerTen(xs,raise);
5062     //             quotient = divideAndRound(rb, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
5063     //         } else {
5064     //             int newScale = checkScaleNonZero((long) xscale - mcp);
5065     //             int raise = checkScaleNonZero((long) newScale - yscale);
5066     //             BigInteger rb = bigMultiplyPowerTen(ys,raise);
5067     //             quotient = divideAndRound(BigInteger.valueOf(xs), rb, scl, roundingMode,checkScaleNonZero(preferredScale));
5068     //         }
5069     //         // doRound, here, only affects 1000000000 case.
5070     //         return doRound(quotient, mc);
5071     //     }
5072 
5073     //     /**
5074     //      * Returns a {@code BigDecimal} whose value is {@code (xs /
5075     //      * ys)}, with rounding according to the context settings.
5076     //      */
5077     //     private static BigDecimal divide(BigInteger xs, int xscale, BigInteger ys, int yscale, long preferredScale, MathContext mc) {
5078     //         // Normalize dividend & divisor so that both fall into [0.1, 0.999...]
5079     //         if (compareMagnitudeNormalized(xs, xscale, ys, yscale) > 0) {// satisfy constraint (b)
5080     //             yscale -= 1; // [that is, divisor *= 10]
5081     //         }
5082     //         int mcp = mc.precision;
5083     //         int roundingMode = mc.roundingMode.oldMode;
5084 
5085     //         // In order to find out whether the divide generates the exact result,
5086     //         // we avoid calling the above divide method. 'quotient' holds the
5087     //         // return BigDecimal object whose scale will be set to 'scl'.
5088     //         BigDecimal quotient;
5089     //         int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp);
5090     //         if (checkScaleNonZero((long) mcp + yscale - xscale) > 0) {
5091     //             int raise = checkScaleNonZero((long) mcp + yscale - xscale);
5092     //             BigInteger rb = bigMultiplyPowerTen(xs,raise);
5093     //             quotient = divideAndRound(rb, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
5094     //         } else {
5095     //             int newScale = checkScaleNonZero((long) xscale - mcp);
5096     //             int raise = checkScaleNonZero((long) newScale - yscale);
5097     //             BigInteger rb = bigMultiplyPowerTen(ys,raise);
5098     //             quotient = divideAndRound(xs, rb, scl, roundingMode,checkScaleNonZero(preferredScale));
5099     //         }
5100     //         // doRound, here, only affects 1000000000 case.
5101     //         return doRound(quotient, mc);
5102     //     }
5103 
5104     //     /*
5105     //      * performs divideAndRound for (dividend0*dividend1, divisor)
5106     //      * returns null if quotient can't fit into long value;
5107     //      */
5108     //     private static BigDecimal multiplyDivideAndRound(long dividend0, long dividend1, long divisor, int scale, int roundingMode,
5109     //                                                      int preferredScale) {
5110     //         int qsign = Long.signum(dividend0)*Long.signum(dividend1)*Long.signum(divisor);
5111     //         dividend0 = MathHelper.abs(dividend0);
5112     //         dividend1 = MathHelper.abs(dividend1);
5113     //         divisor = MathHelper.abs(divisor);
5114     //         // multiply dividend0 * dividend1
5115     //         long d0_hi = dividend0 >>> 32;
5116     //         long d0_lo = dividend0 & LONG_MASK;
5117     //         long d1_hi = dividend1 >>> 32;
5118     //         long d1_lo = dividend1 & LONG_MASK;
5119     //         long product = d0_lo * d1_lo;
5120     //         long d0 = product & LONG_MASK;
5121     //         long d1 = product >>> 32;
5122     //         product = d0_hi * d1_lo + d1;
5123     //         d1 = product & LONG_MASK;
5124     //         long d2 = product >>> 32;
5125     //         product = d0_lo * d1_hi + d1;
5126     //         d1 = product & LONG_MASK;
5127     //         d2 += product >>> 32;
5128     //         long d3 = d2>>>32;
5129     //         d2 &= LONG_MASK;
5130     //         product = d0_hi*d1_hi + d2;
5131     //         d2 = product & LONG_MASK;
5132     //         d3 = ((product>>>32) + d3) & LONG_MASK;
5133     //         final long dividendHi = make64(d3,d2);
5134     //         final long dividendLo = make64(d1,d0);
5135     //         // divide
5136     //         return divideAndRound128(dividendHi, dividendLo, divisor, qsign, scale, roundingMode, preferredScale);
5137     //     }
5138 
5139     //     private static final long DIV_NUM_BASE = (1L<<32); // Number base (32 bits).
5140 
5141     //     /*
5142     //      * divideAndRound 128-bit value by long divisor.
5143     //      * returns null if quotient can't fit into long value;
5144     //      * Specialized version of Knuth's division
5145     //      */
5146     //     private static BigDecimal divideAndRound128(final long dividendHi, final long dividendLo, long divisor, int sign,
5147     //                                                 int scale, int roundingMode, int preferredScale) {
5148     //         if (dividendHi >= divisor) {
5149     //             return null;
5150     //         }
5151 
5152     //         final int shift = Long.numberOfLeadingZeros(divisor);
5153     //         divisor <<= shift;
5154 
5155     //         final long v1 = divisor >>> 32;
5156     //         final long v0 = divisor & LONG_MASK;
5157 
5158     //         long tmp = dividendLo << shift;
5159     //         long u1 = tmp >>> 32;
5160     //         long u0 = tmp & LONG_MASK;
5161 
5162     //         tmp = (dividendHi << shift) | (dividendLo >>> 64 - shift);
5163     //         long u2 = tmp & LONG_MASK;
5164     //         long q1, r_tmp;
5165     //         if (v1 == 1) {
5166     //             q1 = tmp;
5167     //             r_tmp = 0;
5168     //         } else if (tmp >= 0) {
5169     //             q1 = tmp / v1;
5170     //             r_tmp = tmp - q1 * v1;
5171     //         } else {
5172     //             long[] rq = divRemNegativeLong(tmp, v1);
5173     //             q1 = rq[1];
5174     //             r_tmp = rq[0];
5175     //         }
5176 
5177     //         while(q1 >= DIV_NUM_BASE || unsignedLongCompare(q1*v0, make64(r_tmp, u1))) {
5178     //             q1--;
5179     //             r_tmp += v1;
5180     //             if (r_tmp >= DIV_NUM_BASE)
5181     //                 break;
5182     //         }
5183 
5184     //         tmp = mulsub(u2,u1,v1,v0,q1);
5185     //         u1 = tmp & LONG_MASK;
5186     //         long q0;
5187     //         if (v1 == 1) {
5188     //             q0 = tmp;
5189     //             r_tmp = 0;
5190     //         } else if (tmp >= 0) {
5191     //             q0 = tmp / v1;
5192     //             r_tmp = tmp - q0 * v1;
5193     //         } else {
5194     //             long[] rq = divRemNegativeLong(tmp, v1);
5195     //             q0 = rq[1];
5196     //             r_tmp = rq[0];
5197     //         }
5198 
5199     //         while(q0 >= DIV_NUM_BASE || unsignedLongCompare(q0*v0,make64(r_tmp,u0))) {
5200     //             q0--;
5201     //             r_tmp += v1;
5202     //             if (r_tmp >= DIV_NUM_BASE)
5203     //                 break;
5204     //         }
5205 
5206     //         if((int)q1 < 0) {
5207     //             // result (which is positive and unsigned here)
5208     //             // can't fit into long due to sign bit is used for value
5209     //             MutableBigInteger mq = new MutableBigInteger(new int[]{(int)q1, (int)q0});
5210     //             if (roundingMode == ROUND_DOWN && scale == preferredScale) {
5211     //                 return mq.toBigDecimal(sign, scale);
5212     //             }
5213     //             long r = mulsub(u1, u0, v1, v0, q0) >>> shift;
5214     //             if (r != 0) {
5215     //                 if(needIncrement(divisor >>> shift, roundingMode, sign, mq, r)){
5216     //                     mq.add(MutableBigInteger.ONE);
5217     //                 }
5218     //                 return mq.toBigDecimal(sign, scale);
5219     //             } else {
5220     //                 if (preferredScale != scale) {
5221     //                     BigInteger intVal =  mq.toBigInteger(sign);
5222     //                     return createAndStripZerosToMatchScale(intVal,scale, preferredScale);
5223     //                 } else {
5224     //                     return mq.toBigDecimal(sign, scale);
5225     //                 }
5226     //             }
5227     //         }
5228 
5229     //         long q = make64(q1,q0);
5230     //         q*=sign;
5231 
5232     //         if (roundingMode == ROUND_DOWN && scale == preferredScale)
5233     //             return valueOf(q, scale);
5234 
5235     //         long r = mulsub(u1, u0, v1, v0, q0) >>> shift;
5236     //         if (r != 0) {
5237     //             bool increment = needIncrement(divisor >>> shift, roundingMode, sign, q, r);
5238     //             return valueOf((increment ? q + sign : q), scale);
5239     //         } else {
5240     //             if (preferredScale != scale) {
5241     //                 return createAndStripZerosToMatchScale(q, scale, preferredScale);
5242     //             } else {
5243     //                 return valueOf(q, scale);
5244     //             }
5245     //         }
5246     //     }
5247 
5248     //     /*
5249     //      * calculate divideAndRound for ldividend*10^raise / divisor
5250     //      * when abs(dividend)==abs(divisor);
5251     //      */
5252     //     private static BigDecimal roundedTenPower(int qsign, int raise, int scale, int preferredScale) {
5253     //         if (scale > preferredScale) {
5254     //             int diff = scale - preferredScale;
5255     //             if(diff < raise) {
5256     //                 return scaledTenPow(raise - diff, qsign, preferredScale);
5257     //             } else {
5258     //                 return valueOf(qsign,scale-raise);
5259     //             }
5260     //         } else {
5261     //             return scaledTenPow(raise, qsign, scale);
5262     //         }
5263     //     }
5264 
5265     //     static BigDecimal scaledTenPow(int n, int sign, int scale) {
5266     //         if (n < LONG_TEN_POWERS_TABLE.length)
5267     //             return valueOf(sign*LONG_TEN_POWERS_TABLE[n],scale);
5268     //         else {
5269     //             BigInteger unscaledVal = bigTenToThe(n);
5270     //             if(sign==-1) {
5271     //                 unscaledVal = unscaledVal.negate();
5272     //             }
5273     //             return new BigDecimal(unscaledVal, INFLATED, scale, n+1);
5274     //         }
5275     //     }
5276 
5277     //     /**
5278     //      * Calculate the quotient and remainder of dividing a negative long by
5279     //      * another long.
5280     //      *
5281     //      * @param n the numerator; must be negative
5282     //      * @param d the denominator; must not be unity
5283     //      * @return a two-element {@long} array with the remainder and quotient in
5284     //      *         the initial and final elements, respectively
5285     //      */
5286     //     private static long[] divRemNegativeLong(long n, long d) {
5287     //         assert n < 0 : "Non-negative numerator " ~ n;
5288     //         assert d != 1 : "Unity denominator";
5289 
5290     //         // Approximate the quotient and remainder
5291     //         long q = (n >>> 1) / (d >>> 1);
5292     //         long r = n - q * d;
5293 
5294     //         // Correct the approximation
5295     //         while (r < 0) {
5296     //             r += d;
5297     //             q--;
5298     //         }
5299     //         while (r >= d) {
5300     //             r -= d;
5301     //             q++;
5302     //         }
5303 
5304     //         // n - q*d == r && 0 <= r < d, hence we're done.
5305     //         return new long[] {r, q};
5306     //     }
5307 
5308     //     private static long make64(long hi, long lo) {
5309     //         return hi<<32 | lo;
5310     //     }
5311 
5312     //     private static long mulsub(long u1, long u0, final long v1, final long v0, long q0) {
5313     //         long tmp = u0 - q0*v0;
5314     //         return make64(u1 + (tmp>>>32) - q0*v1,tmp & LONG_MASK);
5315     //     }
5316 
5317     //     private static bool unsignedLongCompare(long one, long two) {
5318     //         return (one+Long.MIN_VALUE) > (two+Long.MIN_VALUE);
5319     //     }
5320 
5321     //     private static bool unsignedLongCompareEq(long one, long two) {
5322     //         return (one+Long.MIN_VALUE) >= (two+Long.MIN_VALUE);
5323     //     }
5324 
5325     //     // Compare Normalize dividend & divisor so that both fall into [0.1, 0.999...]
5326     //     private static int compareMagnitudeNormalized(long xs, int xscale, long ys, int yscale) {
5327     //         // assert xs!=0 && ys!=0
5328     //         int sdiff = xscale - yscale;
5329     //         if (sdiff != 0) {
5330     //             if (sdiff < 0) {
5331     //                 xs = longMultiplyPowerTen(xs, -sdiff);
5332     //             } else { // sdiff > 0
5333     //                 ys = longMultiplyPowerTen(ys, sdiff);
5334     //             }
5335     //         }
5336     //         if (xs != INFLATED)
5337     //             return (ys != INFLATED) ? longCompareMagnitude(xs, ys) : -1;
5338     //         else
5339     //             return 1;
5340     //     }
5341 
5342     //     // Compare Normalize dividend & divisor so that both fall into [0.1, 0.999...]
5343     //     private static int compareMagnitudeNormalized(long xs, int xscale, BigInteger ys, int yscale) {
5344     //         // assert "ys can't be represented as long"
5345     //         if (xs == 0)
5346     //             return -1;
5347     //         int sdiff = xscale - yscale;
5348     //         if (sdiff < 0) {
5349     //             if (longMultiplyPowerTen(xs, -sdiff) == INFLATED ) {
5350     //                 return bigMultiplyPowerTen(xs, -sdiff).compareMagnitude(ys);
5351     //             }
5352     //         }
5353     //         return -1;
5354     //     }
5355 
5356     //     // Compare Normalize dividend & divisor so that both fall into [0.1, 0.999...]
5357     //     private static int compareMagnitudeNormalized(BigInteger xs, int xscale, BigInteger ys, int yscale) {
5358     //         int sdiff = xscale - yscale;
5359     //         if (sdiff < 0) {
5360     //             return bigMultiplyPowerTen(xs, -sdiff).compareMagnitude(ys);
5361     //         } else { // sdiff >= 0
5362     //             return xs.compareMagnitude(bigMultiplyPowerTen(ys, sdiff));
5363     //         }
5364     //     }
5365 
5366     //     private static long multiply(long x, long y){
5367     //                 long product = x * y;
5368     //         long ax = MathHelper.abs(x);
5369     //         long ay = MathHelper.abs(y);
5370     //         if (((ax | ay) >>> 31 == 0) || (y == 0) || (product / y == x)){
5371     //                         return product;
5372     //                 }
5373     //         return INFLATED;
5374     //     }
5375 
5376     //     private static BigDecimal multiply(long x, long y, int scale) {
5377     //         long product = multiply(x, y);
5378     //         if(product!=INFLATED) {
5379     //             return valueOf(product,scale);
5380     //         }
5381     //         return new BigDecimal(BigInteger.valueOf(x).multiply(y),INFLATED,scale,0);
5382     //     }
5383 
5384     //     private static BigDecimal multiply(long x, BigInteger y, int scale) {
5385     //         if(x==0) {
5386     //             return zeroValueOf(scale);
5387     //         }
5388     //         return new BigDecimal(y.multiply(x),INFLATED,scale,0);
5389     //     }
5390 
5391     //     private static BigDecimal multiply(BigInteger x, BigInteger y, int scale) {
5392     //         return new BigDecimal(x.multiply(y),INFLATED,scale,0);
5393     //     }
5394 
5395     //     /**
5396     //      * Multiplies two long values and rounds according {@code MathContext}
5397     //      */
5398     //     private static BigDecimal multiplyAndRound(long x, long y, int scale, MathContext mc) {
5399     //         long product = multiply(x, y);
5400     //         if(product!=INFLATED) {
5401     //             return doRound(product, scale, mc);
5402     //         }
5403     //         // attempt to do it in 128 bits
5404     //         int rsign = 1;
5405     //         if(x < 0) {
5406     //             x = -x;
5407     //             rsign = -1;
5408     //         }
5409     //         if(y < 0) {
5410     //             y = -y;
5411     //             rsign *= -1;
5412     //         }
5413     //         // multiply dividend0 * dividend1
5414     //         long m0_hi = x >>> 32;
5415     //         long m0_lo = x & LONG_MASK;
5416     //         long m1_hi = y >>> 32;
5417     //         long m1_lo = y & LONG_MASK;
5418     //         product = m0_lo * m1_lo;
5419     //         long m0 = product & LONG_MASK;
5420     //         long m1 = product >>> 32;
5421     //         product = m0_hi * m1_lo + m1;
5422     //         m1 = product & LONG_MASK;
5423     //         long m2 = product >>> 32;
5424     //         product = m0_lo * m1_hi + m1;
5425     //         m1 = product & LONG_MASK;
5426     //         m2 += product >>> 32;
5427     //         long m3 = m2>>>32;
5428     //         m2 &= LONG_MASK;
5429     //         product = m0_hi*m1_hi + m2;
5430     //         m2 = product & LONG_MASK;
5431     //         m3 = ((product>>>32) + m3) & LONG_MASK;
5432     //         final long mHi = make64(m3,m2);
5433     //         final long mLo = make64(m1,m0);
5434     //         BigDecimal res = doRound128(mHi, mLo, rsign, scale, mc);
5435     //         if(res!=null) {
5436     //             return res;
5437     //         }
5438     //         res = new BigDecimal(BigInteger.valueOf(x).multiply(y*rsign), INFLATED, scale, 0);
5439     //         return doRound(res,mc);
5440     //     }
5441 
5442     //     private static BigDecimal multiplyAndRound(long x, BigInteger y, int scale, MathContext mc) {
5443     //         if(x==0) {
5444     //             return zeroValueOf(scale);
5445     //         }
5446     //         return doRound(y.multiply(x), scale, mc);
5447     //     }
5448 
5449     //     private static BigDecimal multiplyAndRound(BigInteger x, BigInteger y, int scale, MathContext mc) {
5450     //         return doRound(x.multiply(y), scale, mc);
5451     //     }
5452 
5453     //     /**
5454     //      * rounds 128-bit value according {@code MathContext}
5455     //      * returns null if result can't be repsented as compact BigDecimal.
5456     //      */
5457     //     private static BigDecimal doRound128(long hi, long lo, int sign, int scale, MathContext mc) {
5458     //         int mcp = mc.precision;
5459     //         int drop;
5460     //         BigDecimal res = null;
5461     //         if(((drop = precision(hi, lo) - mcp) > 0)&&(drop<LONG_TEN_POWERS_TABLE.length)) {
5462     //             scale = checkScaleNonZero((long)scale - drop);
5463     //             res = divideAndRound128(hi, lo, LONG_TEN_POWERS_TABLE[drop], sign, scale, mc.roundingMode.oldMode, scale);
5464     //         }
5465     //         if(res!=null) {
5466     //             return doRound(res,mc);
5467     //         }
5468     //         return null;
5469     //     }
5470 
5471     //     private static final long[][] LONGLONG_TEN_POWERS_TABLE = {
5472     //         {   0L, 0x8AC7230489E80000L },  //10^19
5473     //         {       0x5L, 0x6bc75e2d63100000L },  //10^20
5474     //         {       0x36L, 0x35c9adc5dea00000L },  //10^21
5475     //         {       0x21eL, 0x19e0c9bab2400000L  },  //10^22
5476     //         {       0x152dL, 0x02c7e14af6800000L  },  //10^23
5477     //         {       0xd3c2L, 0x1bcecceda1000000L  },  //10^24
5478     //         {       0x84595L, 0x161401484a000000L  },  //10^25
5479     //         {       0x52b7d2L, 0xdcc80cd2e4000000L  },  //10^26
5480     //         {       0x33b2e3cL, 0x9fd0803ce8000000L  },  //10^27
5481     //         {       0x204fce5eL, 0x3e25026110000000L  },  //10^28
5482     //         {       0x1431e0faeL, 0x6d7217caa0000000L  },  //10^29
5483     //         {       0xc9f2c9cd0L, 0x4674edea40000000L  },  //10^30
5484     //         {       0x7e37be2022L, 0xc0914b2680000000L  },  //10^31
5485     //         {       0x4ee2d6d415bL, 0x85acef8100000000L  },  //10^32
5486     //         {       0x314dc6448d93L, 0x38c15b0a00000000L  },  //10^33
5487     //         {       0x1ed09bead87c0L, 0x378d8e6400000000L  },  //10^34
5488     //         {       0x13426172c74d82L, 0x2b878fe800000000L  },  //10^35
5489     //         {       0xc097ce7bc90715L, 0xb34b9f1000000000L  },  //10^36
5490     //         {       0x785ee10d5da46d9L, 0x00f436a000000000L  },  //10^37
5491     //         {       0x4b3b4ca85a86c47aL, 0x098a224000000000L  },  //10^38
5492     //     };
5493 
5494     //     /*
5495     //      * returns precision of 128-bit value
5496     //      */
5497     //     private static int precision(long hi, long lo){
5498     //         if(hi==0) {
5499     //             if(lo>=0) {
5500     //                 return longDigitLength(lo);
5501     //             }
5502     //             return (unsignedLongCompareEq(lo, LONGLONG_TEN_POWERS_TABLE[0][1])) ? 20 : 19;
5503     //             // 0x8AC7230489E80000L  = unsigned 2^19
5504     //         }
5505     //         int r = ((128 - Long.numberOfLeadingZeros(hi) + 1) * 1233) >>> 12;
5506     //         int idx = r-19;
5507     //         return (idx >= LONGLONG_TEN_POWERS_TABLE.length || longLongCompareMagnitude(hi, lo,
5508     //                                                                                     LONGLONG_TEN_POWERS_TABLE[idx][0], LONGLONG_TEN_POWERS_TABLE[idx][1])) ? r : r + 1;
5509     //     }
5510 
5511     //     /*
5512     //      * returns true if 128 bit number <hi0,lo0> is less than <hi1,lo1>
5513     //      * hi0 & hi1 should be non-negative
5514     //      */
5515     //     private static bool longLongCompareMagnitude(long hi0, long lo0, long hi1, long lo1) {
5516     //         if(hi0!=hi1) {
5517     //             return hi0<hi1;
5518     //         }
5519     //         return (lo0+Long.MIN_VALUE) <(lo1+Long.MIN_VALUE);
5520     //     }
5521 
5522     //     private static BigDecimal divide(long dividend, int dividendScale, long divisor, int divisorScale, int scale, int roundingMode) {
5523     //         if (checkScale(dividend,(long)scale + divisorScale) > dividendScale) {
5524     //             int newScale = scale + divisorScale;
5525     //             int raise = newScale - dividendScale;
5526     //             if(raise<LONG_TEN_POWERS_TABLE.length) {
5527     //                 long xs = dividend;
5528     //                 if ((xs = longMultiplyPowerTen(xs, raise)) != INFLATED) {
5529     //                     return divideAndRound(xs, divisor, scale, roundingMode, scale);
5530     //                 }
5531     //                 BigDecimal q = multiplyDivideAndRound(LONG_TEN_POWERS_TABLE[raise], dividend, divisor, scale, roundingMode, scale);
5532     //                 if(q!=null) {
5533     //                     return q;
5534     //                 }
5535     //             }
5536     //             BigInteger scaledDividend = bigMultiplyPowerTen(dividend, raise);
5537     //             return divideAndRound(scaledDividend, divisor, scale, roundingMode, scale);
5538     //         } else {
5539     //             int newScale = checkScale(divisor,(long)dividendScale - scale);
5540     //             int raise = newScale - divisorScale;
5541     //             if(raise<LONG_TEN_POWERS_TABLE.length) {
5542     //                 long ys = divisor;
5543     //                 if ((ys = longMultiplyPowerTen(ys, raise)) != INFLATED) {
5544     //                     return divideAndRound(dividend, ys, scale, roundingMode, scale);
5545     //                 }
5546     //             }
5547     //             BigInteger scaledDivisor = bigMultiplyPowerTen(divisor, raise);
5548     //             return divideAndRound(BigInteger.valueOf(dividend), scaledDivisor, scale, roundingMode, scale);
5549     //         }
5550     //     }
5551 
5552     //     private static BigDecimal divide(BigInteger dividend, int dividendScale, long divisor, int divisorScale, int scale, int roundingMode) {
5553     //         if (checkScale(dividend,(long)scale + divisorScale) > dividendScale) {
5554     //             int newScale = scale + divisorScale;
5555     //             int raise = newScale - dividendScale;
5556     //             BigInteger scaledDividend = bigMultiplyPowerTen(dividend, raise);
5557     //             return divideAndRound(scaledDividend, divisor, scale, roundingMode, scale);
5558     //         } else {
5559     //             int newScale = checkScale(divisor,(long)dividendScale - scale);
5560     //             int raise = newScale - divisorScale;
5561     //             if(raise<LONG_TEN_POWERS_TABLE.length) {
5562     //                 long ys = divisor;
5563     //                 if ((ys = longMultiplyPowerTen(ys, raise)) != INFLATED) {
5564     //                     return divideAndRound(dividend, ys, scale, roundingMode, scale);
5565     //                 }
5566     //             }
5567     //             BigInteger scaledDivisor = bigMultiplyPowerTen(divisor, raise);
5568     //             return divideAndRound(dividend, scaledDivisor, scale, roundingMode, scale);
5569     //         }
5570     //     }
5571 
5572     //     private static BigDecimal divide(long dividend, int dividendScale, BigInteger divisor, int divisorScale, int scale, int roundingMode) {
5573     //         if (checkScale(dividend,(long)scale + divisorScale) > dividendScale) {
5574     //             int newScale = scale + divisorScale;
5575     //             int raise = newScale - dividendScale;
5576     //             BigInteger scaledDividend = bigMultiplyPowerTen(dividend, raise);
5577     //             return divideAndRound(scaledDividend, divisor, scale, roundingMode, scale);
5578     //         } else {
5579     //             int newScale = checkScale(divisor,(long)dividendScale - scale);
5580     //             int raise = newScale - divisorScale;
5581     //             BigInteger scaledDivisor = bigMultiplyPowerTen(divisor, raise);
5582     //             return divideAndRound(BigInteger.valueOf(dividend), scaledDivisor, scale, roundingMode, scale);
5583     //         }
5584     //     }
5585 
5586     //     private static BigDecimal divide(BigInteger dividend, int dividendScale, BigInteger divisor, int divisorScale, int scale, int roundingMode) {
5587     //         if (checkScale(dividend,(long)scale + divisorScale) > dividendScale) {
5588     //             int newScale = scale + divisorScale;
5589     //             int raise = newScale - dividendScale;
5590     //             BigInteger scaledDividend = bigMultiplyPowerTen(dividend, raise);
5591     //             return divideAndRound(scaledDividend, divisor, scale, roundingMode, scale);
5592     //         } else {
5593     //             int newScale = checkScale(divisor,(long)dividendScale - scale);
5594     //             int raise = newScale - divisorScale;
5595     //             BigInteger scaledDivisor = bigMultiplyPowerTen(divisor, raise);
5596     //             return divideAndRound(dividend, scaledDivisor, scale, roundingMode, scale);
5597     //         }
5598     //     }
5599 
5600     /**
5601      * Returns the value of the specified number as an {@code int}.
5602      *
5603      * @return  the numeric value represented by this object after conversion
5604      *          to type {@code int}.
5605      */
5606     override int intValue()
5607     {
5608         return int.init;
5609     }
5610 
5611     /**
5612      * Returns the value of the specified number as a {@code long}.
5613      *
5614      * @return  the numeric value represented by this object after conversion
5615      *          to type {@code long}.
5616      */
5617     override long longValue()
5618     {
5619         return long.init;
5620     }
5621 
5622     /**
5623      * Returns the value of the specified number as a {@code float}.
5624      *
5625      * @return  the numeric value represented by this object after conversion
5626      *          to type {@code float}.
5627      */
5628     override float floatValue()
5629     {
5630         return float.init;
5631     }
5632 
5633     /**
5634      * Returns the value of the specified number as a {@code double}.
5635      *
5636      * @return  the numeric value represented by this object after conversion
5637      *          to type {@code double}.
5638      */
5639     override double doubleValue()
5640     {
5641         return double.init;
5642     }
5643 
5644     /**
5645      * Returns the value of the specified number as a {@code byte}.
5646      *
5647      * <p>This implementation returns the result of {@link #intValue} cast
5648      * to a {@code byte}.
5649      *
5650      * @return  the numeric value represented by this object after conversion
5651      *          to type {@code byte}.
5652      */
5653     override byte byteValue()
5654     {
5655         return byte.init;
5656     }
5657 
5658     /**
5659      * Returns the value of the specified number as a {@code short}.
5660      *
5661      * <p>This implementation returns the result of {@link #intValue} cast
5662      * to a {@code short}.
5663      *
5664      * @return  the numeric value represented by this object after conversion
5665      *          to type {@code short}.
5666      */
5667     override short shortValue()
5668     {
5669         return short.init;
5670     }
5671 
5672     override string toString()
5673     {
5674         return super.toString();
5675     }
5676 
5677 }
5678 
5679 public class RoundingMode
5680 {
5681 
5682     /**
5683          * Rounding mode to round away from zero.  Always increments the
5684          * digit prior to a non-zero discarded fraction.  Note that this
5685          * rounding mode never decreases the magnitude of the calculated
5686          * value.
5687          *
5688          *<p>Example:
5689          *<table border>
5690          * <caption><b>Rounding mode UP Examples</b></caption>
5691          *<tr valign=top><th>Input Number</th>
5692          *    <th>Input rounded to one digit<br> with {@code UP} rounding
5693          *<tr align=right><td>5.5</td>  <td>6</td>
5694          *<tr align=right><td>2.5</td>  <td>3</td>
5695          *<tr align=right><td>1.6</td>  <td>2</td>
5696          *<tr align=right><td>1.1</td>  <td>2</td>
5697          *<tr align=right><td>1.0</td>  <td>1</td>
5698          *<tr align=right><td>-1.0</td> <td>-1</td>
5699          *<tr align=right><td>-1.1</td> <td>-2</td>
5700          *<tr align=right><td>-1.6</td> <td>-2</td>
5701          *<tr align=right><td>-2.5</td> <td>-3</td>
5702          *<tr align=right><td>-5.5</td> <td>-6</td>
5703          *</table>
5704          */
5705     static RoundingMode UP;
5706 
5707     /**
5708          * Rounding mode to round towards zero.  Never increments the digit
5709          * prior to a discarded fraction (i.e., truncates).  Note that this
5710          * rounding mode never increases the magnitude of the calculated value.
5711          *
5712          *<p>Example:
5713          *<table border>
5714          * <caption><b>Rounding mode DOWN Examples</b></caption>
5715          *<tr valign=top><th>Input Number</th>
5716          *    <th>Input rounded to one digit<br> with {@code DOWN} rounding
5717          *<tr align=right><td>5.5</td>  <td>5</td>
5718          *<tr align=right><td>2.5</td>  <td>2</td>
5719          *<tr align=right><td>1.6</td>  <td>1</td>
5720          *<tr align=right><td>1.1</td>  <td>1</td>
5721          *<tr align=right><td>1.0</td>  <td>1</td>
5722          *<tr align=right><td>-1.0</td> <td>-1</td>
5723          *<tr align=right><td>-1.1</td> <td>-1</td>
5724          *<tr align=right><td>-1.6</td> <td>-1</td>
5725          *<tr align=right><td>-2.5</td> <td>-2</td>
5726          *<tr align=right><td>-5.5</td> <td>-5</td>
5727          *</table>
5728          */
5729     static RoundingMode DOWN;
5730 
5731     /**
5732          * Rounding mode to round towards positive infinity.  If the
5733          * result is positive, behaves as for {@code RoundingMode.UP};
5734          * if negative, behaves as for {@code RoundingMode.DOWN}.  Note
5735          * that this rounding mode never decreases the calculated value.
5736          *
5737          *<p>Example:
5738          *<table border>
5739          * <caption><b>Rounding mode CEILING Examples</b></caption>
5740          *<tr valign=top><th>Input Number</th>
5741          *    <th>Input rounded to one digit<br> with {@code CEILING} rounding
5742          *<tr align=right><td>5.5</td>  <td>6</td>
5743          *<tr align=right><td>2.5</td>  <td>3</td>
5744          *<tr align=right><td>1.6</td>  <td>2</td>
5745          *<tr align=right><td>1.1</td>  <td>2</td>
5746          *<tr align=right><td>1.0</td>  <td>1</td>
5747          *<tr align=right><td>-1.0</td> <td>-1</td>
5748          *<tr align=right><td>-1.1</td> <td>-1</td>
5749          *<tr align=right><td>-1.6</td> <td>-1</td>
5750          *<tr align=right><td>-2.5</td> <td>-2</td>
5751          *<tr align=right><td>-5.5</td> <td>-5</td>
5752          *</table>
5753          */
5754     static RoundingMode CEILING;
5755 
5756     /**
5757          * Rounding mode to round towards negative infinity.  If the
5758          * result is positive, behave as for {@code RoundingMode.DOWN};
5759          * if negative, behave as for {@code RoundingMode.UP}.  Note that
5760          * this rounding mode never increases the calculated value.
5761          *
5762          *<p>Example:
5763          *<table border>
5764          * <caption><b>Rounding mode FLOOR Examples</b></caption>
5765          *<tr valign=top><th>Input Number</th>
5766          *    <th>Input rounded to one digit<br> with {@code FLOOR} rounding
5767          *<tr align=right><td>5.5</td>  <td>5</td>
5768          *<tr align=right><td>2.5</td>  <td>2</td>
5769          *<tr align=right><td>1.6</td>  <td>1</td>
5770          *<tr align=right><td>1.1</td>  <td>1</td>
5771          *<tr align=right><td>1.0</td>  <td>1</td>
5772          *<tr align=right><td>-1.0</td> <td>-1</td>
5773          *<tr align=right><td>-1.1</td> <td>-2</td>
5774          *<tr align=right><td>-1.6</td> <td>-2</td>
5775          *<tr align=right><td>-2.5</td> <td>-3</td>
5776          *<tr align=right><td>-5.5</td> <td>-6</td>
5777          *</table>
5778          */
5779     static RoundingMode FLOOR;
5780 
5781     /**
5782          * Rounding mode to round towards {@literal "nearest neighbor"}
5783          * unless both neighbors are equidistant, in which case round up.
5784          * Behaves as for {@code RoundingMode.UP} if the discarded
5785          * fraction is &ge; 0.5; otherwise, behaves as for
5786          * {@code RoundingMode.DOWN}.  Note that this is the rounding
5787          * mode commonly taught at school.
5788          *
5789          *<p>Example:
5790          *<table border>
5791          * <caption><b>Rounding mode HALF_UP Examples</b></caption>
5792          *<tr valign=top><th>Input Number</th>
5793          *    <th>Input rounded to one digit<br> with {@code HALF_UP} rounding
5794          *<tr align=right><td>5.5</td>  <td>6</td>
5795          *<tr align=right><td>2.5</td>  <td>3</td>
5796          *<tr align=right><td>1.6</td>  <td>2</td>
5797          *<tr align=right><td>1.1</td>  <td>1</td>
5798          *<tr align=right><td>1.0</td>  <td>1</td>
5799          *<tr align=right><td>-1.0</td> <td>-1</td>
5800          *<tr align=right><td>-1.1</td> <td>-1</td>
5801          *<tr align=right><td>-1.6</td> <td>-2</td>
5802          *<tr align=right><td>-2.5</td> <td>-3</td>
5803          *<tr align=right><td>-5.5</td> <td>-6</td>
5804          *</table>
5805          */
5806     static RoundingMode HALF_UP;
5807 
5808     /**
5809          * Rounding mode to round towards {@literal "nearest neighbor"}
5810          * unless both neighbors are equidistant, in which case round
5811          * down.  Behaves as for {@code RoundingMode.UP} if the discarded
5812          * fraction is &gt; 0.5; otherwise, behaves as for
5813          * {@code RoundingMode.DOWN}.
5814          *
5815          *<p>Example:
5816          *<table border>
5817          * <caption><b>Rounding mode HALF_DOWN Examples</b></caption>
5818          *<tr valign=top><th>Input Number</th>
5819          *    <th>Input rounded to one digit<br> with {@code HALF_DOWN} rounding
5820          *<tr align=right><td>5.5</td>  <td>5</td>
5821          *<tr align=right><td>2.5</td>  <td>2</td>
5822          *<tr align=right><td>1.6</td>  <td>2</td>
5823          *<tr align=right><td>1.1</td>  <td>1</td>
5824          *<tr align=right><td>1.0</td>  <td>1</td>
5825          *<tr align=right><td>-1.0</td> <td>-1</td>
5826          *<tr align=right><td>-1.1</td> <td>-1</td>
5827          *<tr align=right><td>-1.6</td> <td>-2</td>
5828          *<tr align=right><td>-2.5</td> <td>-2</td>
5829          *<tr align=right><td>-5.5</td> <td>-5</td>
5830          *</table>
5831          */
5832     static RoundingMode HALF_DOWN;
5833 
5834     /**
5835          * Rounding mode to round towards the {@literal "nearest neighbor"}
5836          * unless both neighbors are equidistant, in which case, round
5837          * towards the even neighbor.  Behaves as for
5838          * {@code RoundingMode.HALF_UP} if the digit to the left of the
5839          * discarded fraction is odd; behaves as for
5840          * {@code RoundingMode.HALF_DOWN} if it's even.  Note that this
5841          * is the rounding mode that statistically minimizes cumulative
5842          * error when applied repeatedly over a sequence of calculations.
5843          * It is sometimes known as {@literal "Banker's rounding,"} and is
5844          * chiefly used in the USA.  This rounding mode is analogous to
5845          * the rounding policy used for {@code float} and {@code double}
5846          * arithmetic in Java.
5847          *
5848          *<p>Example:
5849          *<table border>
5850          * <caption><b>Rounding mode HALF_EVEN Examples</b></caption>
5851          *<tr valign=top><th>Input Number</th>
5852          *    <th>Input rounded to one digit<br> with {@code HALF_EVEN} rounding
5853          *<tr align=right><td>5.5</td>  <td>6</td>
5854          *<tr align=right><td>2.5</td>  <td>2</td>
5855          *<tr align=right><td>1.6</td>  <td>2</td>
5856          *<tr align=right><td>1.1</td>  <td>1</td>
5857          *<tr align=right><td>1.0</td>  <td>1</td>
5858          *<tr align=right><td>-1.0</td> <td>-1</td>
5859          *<tr align=right><td>-1.1</td> <td>-1</td>
5860          *<tr align=right><td>-1.6</td> <td>-2</td>
5861          *<tr align=right><td>-2.5</td> <td>-2</td>
5862          *<tr align=right><td>-5.5</td> <td>-6</td>
5863          *</table>
5864          */
5865     static RoundingMode HALF_EVEN;
5866 
5867     /**
5868          * Rounding mode to assert that the requested operation has an exact
5869          * result, hence no rounding is necessary.  If this rounding mode is
5870          * specified on an operation that yields an inexact result, an
5871          * {@code ArithmeticException} is thrown.
5872          *<p>Example:
5873          *<table border>
5874          * <caption><b>Rounding mode UNNECESSARY Examples</b></caption>
5875          *<tr valign=top><th>Input Number</th>
5876          *    <th>Input rounded to one digit<br> with {@code UNNECESSARY} rounding
5877          *<tr align=right><td>5.5</td>  <td>throw {@code ArithmeticException}</td>
5878          *<tr align=right><td>2.5</td>  <td>throw {@code ArithmeticException}</td>
5879          *<tr align=right><td>1.6</td>  <td>throw {@code ArithmeticException}</td>
5880          *<tr align=right><td>1.1</td>  <td>throw {@code ArithmeticException}</td>
5881          *<tr align=right><td>1.0</td>  <td>1</td>
5882          *<tr align=right><td>-1.0</td> <td>-1</td>
5883          *<tr align=right><td>-1.1</td> <td>throw {@code ArithmeticException}</td>
5884          *<tr align=right><td>-1.6</td> <td>throw {@code ArithmeticException}</td>
5885          *<tr align=right><td>-2.5</td> <td>throw {@code ArithmeticException}</td>
5886          *<tr align=right><td>-5.5</td> <td>throw {@code ArithmeticException}</td>
5887          *</table>
5888          */
5889     static RoundingMode UNNECESSARY;
5890 
5891     // Corresponding BigDecimal rounding constant
5892     int oldMode;
5893 
5894     static this()
5895     {
5896         UP = new RoundingMode(BigDecimal.ROUND_UP);
5897         DOWN = new RoundingMode(BigDecimal.ROUND_DOWN);
5898         CEILING = new RoundingMode(BigDecimal.ROUND_CEILING);
5899         FLOOR = new RoundingMode(BigDecimal.ROUND_FLOOR);
5900         HALF_UP = new RoundingMode(BigDecimal.ROUND_HALF_UP);
5901         HALF_DOWN = new RoundingMode(BigDecimal.ROUND_HALF_DOWN);
5902         HALF_EVEN = new RoundingMode(BigDecimal.ROUND_HALF_EVEN);
5903         UNNECESSARY = new RoundingMode(BigDecimal.ROUND_UNNECESSARY);
5904     }
5905 
5906     /**
5907      * Constructor
5908      *
5909      * @param oldMode The {@code BigDecimal} constant corresponding to
5910      *        this mode
5911      */
5912     private this(int oldMode)
5913     {
5914         this.oldMode = oldMode;
5915     }
5916 
5917     public int mode()
5918     {
5919         return this.oldMode;
5920     }
5921     /**
5922      * Returns the {@code RoundingMode} object corresponding to a
5923      * legacy integer rounding mode constant in {@link BigDecimal}.
5924      *
5925      * @param  rm legacy integer rounding mode to convert
5926      * @return {@code RoundingMode} corresponding to the given integer.
5927      * @throws IllegalArgumentException integer is out of range
5928      */
5929     public static RoundingMode valueOf(const int rm)
5930     {
5931         switch (rm)
5932         {
5933 
5934         case BigDecimal.ROUND_UP:
5935             return UP;
5936 
5937         case BigDecimal.ROUND_DOWN:
5938             return DOWN;
5939 
5940         case BigDecimal.ROUND_CEILING:
5941             return CEILING;
5942 
5943         case BigDecimal.ROUND_FLOOR:
5944             return FLOOR;
5945 
5946         case BigDecimal.ROUND_HALF_UP:
5947             return HALF_UP;
5948 
5949         case BigDecimal.ROUND_HALF_DOWN:
5950             return HALF_DOWN;
5951 
5952         case BigDecimal.ROUND_HALF_EVEN:
5953             return HALF_EVEN;
5954 
5955         case BigDecimal.ROUND_UNNECESSARY:
5956             return UNNECESSARY;
5957 
5958         default:
5959             throw new IllegalArgumentException("argument out of range");
5960         }
5961     }
5962 }