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