jdk/src/share/classes/java/math/BigDecimal.java
author duke
Sat, 01 Dec 2007 00:00:00 +0000
changeset 2 90ce3da70b43
child 2922 dd6d609861f0
permissions -rw-r--r--
Initial load
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
     2
 * Portions Copyright 1996-2007 Sun Microsystems, Inc.  All Rights Reserved.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Sun designates this
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 * by Sun in the LICENSE file that accompanied this code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 * CA 95054 USA or visit www.sun.com if you need additional information or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 * have any questions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
 * Portions Copyright IBM Corporation, 2001. All Rights Reserved.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
package java.math;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
 * Immutable, arbitrary-precision signed decimal numbers.  A
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
 * {@code BigDecimal} consists of an arbitrary precision integer
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
 * <i>unscaled value</i> and a 32-bit integer <i>scale</i>.  If zero
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
 * or positive, the scale is the number of digits to the right of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 * decimal point.  If negative, the unscaled value of the number is
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
 * multiplied by ten to the power of the negation of the scale.  The
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 * value of the number represented by the {@code BigDecimal} is
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 * therefore <tt>(unscaledValue &times; 10<sup>-scale</sup>)</tt>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 * <p>The {@code BigDecimal} class provides operations for
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 * arithmetic, scale manipulation, rounding, comparison, hashing, and
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 * format conversion.  The {@link #toString} method provides a
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 * canonical representation of a {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 * <p>The {@code BigDecimal} class gives its user complete control
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 * over rounding behavior.  If no rounding mode is specified and the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 * exact result cannot be represented, an exception is thrown;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * otherwise, calculations can be carried out to a chosen precision
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 * and rounding mode by supplying an appropriate {@link MathContext}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 * object to the operation.  In either case, eight <em>rounding
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 * modes</em> are provided for the control of rounding.  Using the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 * integer fields in this class (such as {@link #ROUND_HALF_UP}) to
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 * represent rounding mode is largely obsolete; the enumeration values
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
 * of the {@code RoundingMode} {@code enum}, (such as {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
 * RoundingMode#HALF_UP}) should be used instead.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
 * <p>When a {@code MathContext} object is supplied with a precision
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
 * setting of 0 (for example, {@link MathContext#UNLIMITED}),
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 * arithmetic operations are exact, as are the arithmetic methods
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
 * which take no {@code MathContext} object.  (This is the only
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
 * behavior that was supported in releases prior to 5.)  As a
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
 * corollary of computing the exact result, the rounding mode setting
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
 * of a {@code MathContext} object with a precision setting of 0 is
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
 * not used and thus irrelevant.  In the case of divide, the exact
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
 * quotient could have an infinitely long decimal expansion; for
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
 * example, 1 divided by 3.  If the quotient has a nonterminating
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
 * decimal expansion and the operation is specified to return an exact
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
 * result, an {@code ArithmeticException} is thrown.  Otherwise, the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
 * exact result of the division is returned, as done for other
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
 * operations.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
 * <p>When the precision setting is not 0, the rules of
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
 * {@code BigDecimal} arithmetic are broadly compatible with selected
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
 * modes of operation of the arithmetic defined in ANSI X3.274-1996
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
 * and ANSI X3.274-1996/AM 1-2000 (section 7.4).  Unlike those
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
 * standards, {@code BigDecimal} includes many rounding modes, which
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
 * were mandatory for division in {@code BigDecimal} releases prior
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
 * to 5.  Any conflicts between these ANSI standards and the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
 * {@code BigDecimal} specification are resolved in favor of
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
 * {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
 * <p>Since the same numerical value can have different
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
 * representations (with different scales), the rules of arithmetic
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
 * and rounding must specify both the numerical result and the scale
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
 * used in the result's representation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
 * <p>In general the rounding modes and precision setting determine
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
 * how operations return results with a limited number of digits when
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
 * the exact result has more digits (perhaps infinitely many in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
 * case of division) than the number of digits returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
 * First, the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
 * total number of digits to return is specified by the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
 * {@code MathContext}'s {@code precision} setting; this determines
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
 * the result's <i>precision</i>.  The digit count starts from the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
 * leftmost nonzero digit of the exact result.  The rounding mode
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
 * determines how any discarded trailing digits affect the returned
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
 * result.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
 * <p>For all arithmetic operators , the operation is carried out as
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
 * though an exact intermediate result were first calculated and then
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
 * rounded to the number of digits specified by the precision setting
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
 * (if necessary), using the selected rounding mode.  If the exact
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
 * result is not returned, some digit positions of the exact result
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
 * are discarded.  When rounding increases the magnitude of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
 * returned result, it is possible for a new digit position to be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
 * created by a carry propagating to a leading {@literal "9"} digit.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
 * For example, rounding the value 999.9 to three digits rounding up
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
 * would be numerically equal to one thousand, represented as
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
 * 100&times;10<sup>1</sup>.  In such cases, the new {@literal "1"} is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
 * the leading digit position of the returned result.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
 * <p>Besides a logical exact result, each arithmetic operation has a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
 * preferred scale for representing a result.  The preferred
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
 * scale for each operation is listed in the table below.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
 * <table border>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
 * <caption top><h3>Preferred Scales for Results of Arithmetic Operations
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
 * </h3></caption>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
 * <tr><th>Operation</th><th>Preferred Scale of Result</th></tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
 * <tr><td>Add</td><td>max(addend.scale(), augend.scale())</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
 * <tr><td>Subtract</td><td>max(minuend.scale(), subtrahend.scale())</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
 * <tr><td>Multiply</td><td>multiplier.scale() + multiplicand.scale()</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
 * <tr><td>Divide</td><td>dividend.scale() - divisor.scale()</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
 * </table>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
 * These scales are the ones used by the methods which return exact
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
 * arithmetic results; except that an exact divide may have to use a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
 * larger scale since the exact result may have more digits.  For
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
 * example, {@code 1/32} is {@code 0.03125}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
 * <p>Before rounding, the scale of the logical exact intermediate
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
 * result is the preferred scale for that operation.  If the exact
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
 * numerical result cannot be represented in {@code precision}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
 * digits, rounding selects the set of digits to return and the scale
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
 * of the result is reduced from the scale of the intermediate result
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
 * to the least scale which can represent the {@code precision}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
 * digits actually returned.  If the exact result can be represented
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
 * with at most {@code precision} digits, the representation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
 * of the result with the scale closest to the preferred scale is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
 * returned.  In particular, an exactly representable quotient may be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
 * represented in fewer than {@code precision} digits by removing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
 * trailing zeros and decreasing the scale.  For example, rounding to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
 * three digits using the {@linkplain RoundingMode#FLOOR floor}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
 * rounding mode, <br>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
 * {@code 19/100 = 0.19   // integer=19,  scale=2} <br>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
 * but<br>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
 * {@code 21/110 = 0.190  // integer=190, scale=3} <br>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
 * <p>Note that for add, subtract, and multiply, the reduction in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
 * scale will equal the number of digit positions of the exact result
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
 * which are discarded. If the rounding causes a carry propagation to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
 * create a new high-order digit position, an additional digit of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
 * result is discarded than when no new digit position is created.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
 * <p>Other methods may have slightly different rounding semantics.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
 * For example, the result of the {@code pow} method using the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
 * {@linkplain #pow(int, MathContext) specified algorithm} can
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
 * occasionally differ from the rounded mathematical result by more
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
 * than one unit in the last place, one <i>{@linkplain #ulp() ulp}</i>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
 * <p>Two types of operations are provided for manipulating the scale
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
 * of a {@code BigDecimal}: scaling/rounding operations and decimal
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
 * point motion operations.  Scaling/rounding operations ({@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
 * #setScale setScale} and {@link #round round}) return a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
 * {@code BigDecimal} whose value is approximately (or exactly) equal
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
 * to that of the operand, but whose scale or precision is the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
 * specified value; that is, they increase or decrease the precision
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
 * of the stored number with minimal effect on its value.  Decimal
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
 * point motion operations ({@link #movePointLeft movePointLeft} and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
 * {@link #movePointRight movePointRight}) return a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
 * {@code BigDecimal} created from the operand by moving the decimal
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
 * point a specified distance in the specified direction.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
 * <p>For the sake of brevity and clarity, pseudo-code is used
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
 * throughout the descriptions of {@code BigDecimal} methods.  The
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
 * pseudo-code expression {@code (i + j)} is shorthand for "a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
 * {@code BigDecimal} whose value is that of the {@code BigDecimal}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
 * {@code i} added to that of the {@code BigDecimal}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
 * {@code j}." The pseudo-code expression {@code (i == j)} is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
 * shorthand for "{@code true} if and only if the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
 * {@code BigDecimal} {@code i} represents the same value as the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
 * {@code BigDecimal} {@code j}." Other pseudo-code expressions
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
 * are interpreted similarly.  Square brackets are used to represent
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
 * the particular {@code BigInteger} and scale pair defining a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
 * {@code BigDecimal} value; for example [19, 2] is the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
 * {@code BigDecimal} numerically equal to 0.19 having a scale of 2.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
 * <p>Note: care should be exercised if {@code BigDecimal} objects
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
 * are used as keys in a {@link java.util.SortedMap SortedMap} or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
 * elements in a {@link java.util.SortedSet SortedSet} since
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
 * {@code BigDecimal}'s <i>natural ordering</i> is <i>inconsistent
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
 * with equals</i>.  See {@link Comparable}, {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
 * java.util.SortedMap} or {@link java.util.SortedSet} for more
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
 * information.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
 * <p>All methods and constructors for this class throw
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
 * {@code NullPointerException} when passed a {@code null} object
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
 * reference for any input parameter.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
 * @see     BigInteger
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
 * @see     MathContext
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
 * @see     RoundingMode
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
 * @see     java.util.SortedMap
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
 * @see     java.util.SortedSet
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
 * @author  Josh Bloch
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
 * @author  Mike Cowlishaw
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
 * @author  Joseph D. Darcy
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
public class BigDecimal extends Number implements Comparable<BigDecimal> {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
     * The unscaled value of this BigDecimal, as returned by {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
     * #unscaledValue}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
     * @serial
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
     * @see #unscaledValue
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
    private volatile BigInteger intVal;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
     * The scale of this BigDecimal, as returned by {@link #scale}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
     * @serial
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
     * @see #scale
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
    private int scale = 0;  // Note: this may have any value, so
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
                            // calculations must be done in longs
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
     * The number of decimal digits in this BigDecimal, or 0 if the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
     * number of digits are not known (lookaside information).  If
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
     * nonzero, the value is guaranteed correct.  Use the precision()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
     * method to obtain and set the value if it might be 0.  This
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
     * field is mutable until set nonzero.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
    private volatile transient int precision = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
     * Used to store the canonical string representation, if computed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
    private volatile transient String stringCache = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
     * Sentinel value for {@link #intCompact} indicating the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
     * significand information is only available from {@code intVal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
    private static final long INFLATED = Long.MIN_VALUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
     * If the absolute value of the significand of this BigDecimal is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
     * less than or equal to {@code Long.MAX_VALUE}, the value can be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
     * compactly stored in this field and used in computations.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
    private transient long intCompact = INFLATED;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
    // All 18-digit base ten strings fit into a long; not all 19-digit
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
    // strings will
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
    private static final int MAX_COMPACT_DIGITS = 18;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
    private static final int MAX_BIGINT_BITS = 62;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
    /* Appease the serialization gods */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
    private static final long serialVersionUID = 6108874887143696463L;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
    // Cache of common small BigDecimal values.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
    private static final BigDecimal zeroThroughTen[] = {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
        new BigDecimal(BigInteger.ZERO,         0,  0),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
        new BigDecimal(BigInteger.ONE,          1,  0),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
        new BigDecimal(BigInteger.valueOf(2),   2,  0),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
        new BigDecimal(BigInteger.valueOf(3),   3,  0),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
        new BigDecimal(BigInteger.valueOf(4),   4,  0),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
        new BigDecimal(BigInteger.valueOf(5),   5,  0),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
        new BigDecimal(BigInteger.valueOf(6),   6,  0),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
        new BigDecimal(BigInteger.valueOf(7),   7,  0),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
        new BigDecimal(BigInteger.valueOf(8),   8,  0),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
        new BigDecimal(BigInteger.valueOf(9),   9,  0),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
        new BigDecimal(BigInteger.TEN,          10, 0),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
    };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
    // Constants
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
     * The value 0, with a scale of 0.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
    public static final BigDecimal ZERO =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
        zeroThroughTen[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
     * The value 1, with a scale of 0.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
    public static final BigDecimal ONE =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
        zeroThroughTen[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
     * The value 10, with a scale of 0.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
    public static final BigDecimal TEN =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
        zeroThroughTen[10];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
    // Constructors
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
     * Translates a character array representation of a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
     * {@code BigDecimal} into a {@code BigDecimal}, accepting the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
     * same sequence of characters as the {@link #BigDecimal(String)}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
     * constructor, while allowing a sub-array to be specified.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
     * <p>Note that if the sequence of characters is already available
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
     * within a character array, using this constructor is faster than
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
     * converting the {@code char} array to string and using the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
     * {@code BigDecimal(String)} constructor .
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
     * @param  in {@code char} array that is the source of characters.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
     * @param  offset first character in the array to inspect.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
     * @param  len number of characters to consider.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
     * @throws NumberFormatException if {@code in} is not a valid
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
     *         representation of a {@code BigDecimal} or the defined subarray
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
     *         is not wholly within {@code in}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
    public BigDecimal(char[] in, int offset, int len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
        // This is the primary string to BigDecimal constructor; all
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
        // incoming strings end up here; it uses explicit (inline)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
        // parsing for speed and generates at most one intermediate
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
        // (temporary) object (a char[] array).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
        // use array bounds checking to handle too-long, len == 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
        // bad offset, etc.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
            // handle the sign
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
            boolean isneg = false;          // assume positive
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
            if (in[offset] == '-') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
                isneg = true;               // leading minus means negative
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
                offset++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
                len--;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
            } else if (in[offset] == '+') { // leading + allowed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
                offset++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
                len--;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
            // should now be at numeric part of the significand
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
            int dotoff = -1;                 // '.' offset, -1 if none
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
            int cfirst = offset;             // record start of integer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
            long exp = 0;                    // exponent
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
            if (len > in.length)             // protect against huge length
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
                throw new NumberFormatException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
            char coeff[] = new char[len];    // integer significand array
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
            char c;                          // work
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
            for (; len > 0; offset++, len--) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
                c = in[offset];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
                if ((c >= '0' && c <= '9') || Character.isDigit(c)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
                    // have digit
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
                    coeff[precision] = c;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
                    precision++;             // count of digits
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
                    continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
                if (c == '.') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
                    // have dot
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
                    if (dotoff >= 0)         // two dots
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
                        throw new NumberFormatException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
                    dotoff = offset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
                    continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
                // exponent expected
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
                if ((c != 'e') && (c != 'E'))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
                    throw new NumberFormatException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
                offset++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
                c = in[offset];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
                len--;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
                boolean negexp = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
                // optional sign
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
                if (c == '-' || c == '+') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
                    negexp = (c == '-');
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
                    offset++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
                    c = in[offset];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
                    len--;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
                if (len <= 0)    // no exponent digits
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
                    throw new NumberFormatException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
                // skip leading zeros in the exponent
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
                while (len > 10 && Character.digit(c, 10) == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
                        offset++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
                        c = in[offset];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
                        len--;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
                if (len > 10)  // too many nonzero exponent digits
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
                    throw new NumberFormatException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
                // c now holds first digit of exponent
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
                for (;; len--) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
                    int v;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
                    if (c >= '0' && c <= '9') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
                        v = c - '0';
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
                        v = Character.digit(c, 10);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
                        if (v < 0)            // not a digit
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
                            throw new NumberFormatException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
                    exp = exp * 10 + v;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
                    if (len == 1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
                        break;               // that was final character
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
                    offset++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
                    c = in[offset];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
                if (negexp)                  // apply sign
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
                    exp = -exp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
                // Next test is required for backwards compatibility
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
                if ((int)exp != exp)         // overflow
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
                    throw new NumberFormatException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
                break;                       // [saves a test]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
            // here when no characters left
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
            if (precision == 0)              // no digits found
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
                throw new NumberFormatException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
            if (dotoff >= 0) {               // had dot; set scale
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
                scale = precision - (dotoff - cfirst);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
                // [cannot overflow]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
            if (exp != 0) {                  // had significant exponent
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
                    scale = checkScale(-exp + scale); // adjust
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
                } catch (ArithmeticException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
                    throw new NumberFormatException("Scale out of range.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
            // Remove leading zeros from precision (digits count)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
            int first = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
            for (; (coeff[first] == '0' || Character.digit(coeff[first], 10) == 0) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
                     precision > 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
                 first++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
                precision--;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
            // Set the significand ..
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
            // Copy significand to exact-sized array, with sign if
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
            // negative
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
            // Later use: BigInteger(coeff, first, precision) for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
            //   both cases, by allowing an extra char at the front of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
            //   coeff.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
            char quick[];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
            if (!isneg) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
                quick = new char[precision];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
                System.arraycopy(coeff, first, quick, 0, precision);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
                quick = new char[precision+1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
                quick[0] = '-';
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
                System.arraycopy(coeff, first, quick, 1, precision);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
            if (precision <= MAX_COMPACT_DIGITS)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
                intCompact = Long.parseLong(new String(quick));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
            else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
                intVal = new BigInteger(quick);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
            // System.out.println(" new: " +intVal+" ["+scale+"] "+precision);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
        } catch (ArrayIndexOutOfBoundsException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
            throw new NumberFormatException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
        } catch (NegativeArraySizeException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
            throw new NumberFormatException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
     * Translates a character array representation of a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
     * {@code BigDecimal} into a {@code BigDecimal}, accepting the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
     * same sequence of characters as the {@link #BigDecimal(String)}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
     * constructor, while allowing a sub-array to be specified and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
     * with rounding according to the context settings.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
     * <p>Note that if the sequence of characters is already available
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
     * within a character array, using this constructor is faster than
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
     * converting the {@code char} array to string and using the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
     * {@code BigDecimal(String)} constructor .
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
     * @param  in {@code char} array that is the source of characters.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
     * @param  offset first character in the array to inspect.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
     * @param  len number of characters to consider..
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
     * @param  mc the context to use.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
     * @throws ArithmeticException if the result is inexact but the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
     *         rounding mode is {@code UNNECESSARY}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
     * @throws NumberFormatException if {@code in} is not a valid
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
     *         representation of a {@code BigDecimal} or the defined subarray
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
     *         is not wholly within {@code in}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
    public BigDecimal(char[] in, int offset, int len, MathContext mc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
        this(in, offset, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
        if (mc.precision > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
            roundThis(mc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
     * Translates a character array representation of a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
     * {@code BigDecimal} into a {@code BigDecimal}, accepting the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
     * same sequence of characters as the {@link #BigDecimal(String)}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
     * constructor.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
     * <p>Note that if the sequence of characters is already available
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
     * as a character array, using this constructor is faster than
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
     * converting the {@code char} array to string and using the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
     * {@code BigDecimal(String)} constructor .
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
     * @param in {@code char} array that is the source of characters.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
     * @throws NumberFormatException if {@code in} is not a valid
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
     *         representation of a {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
    public BigDecimal(char[] in) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
        this(in, 0, in.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
     * Translates a character array representation of a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
     * {@code BigDecimal} into a {@code BigDecimal}, accepting the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
     * same sequence of characters as the {@link #BigDecimal(String)}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
     * constructor and with rounding according to the context
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
     * settings.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
     * <p>Note that if the sequence of characters is already available
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
     * as a character array, using this constructor is faster than
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
     * converting the {@code char} array to string and using the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
     * {@code BigDecimal(String)} constructor .
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
     * @param  in {@code char} array that is the source of characters.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
     * @param  mc the context to use.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
     * @throws ArithmeticException if the result is inexact but the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
     *         rounding mode is {@code UNNECESSARY}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
     * @throws NumberFormatException if {@code in} is not a valid
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
     *         representation of a {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
    public BigDecimal(char[] in, MathContext mc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
        this(in, 0, in.length, mc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
     * Translates the string representation of a {@code BigDecimal}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
     * into a {@code BigDecimal}.  The string representation consists
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
     * of an optional sign, {@code '+'} (<tt> '&#92;u002B'</tt>) or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
     * {@code '-'} (<tt>'&#92;u002D'</tt>), followed by a sequence of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
     * zero or more decimal digits ("the integer"), optionally
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
     * followed by a fraction, optionally followed by an exponent.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
     * <p>The fraction consists of a decimal point followed by zero
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
     * or more decimal digits.  The string must contain at least one
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
     * digit in either the integer or the fraction.  The number formed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
     * by the sign, the integer and the fraction is referred to as the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
     * <i>significand</i>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
     * <p>The exponent consists of the character {@code 'e'}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
     * (<tt>'&#92;u0065'</tt>) or {@code 'E'} (<tt>'&#92;u0045'</tt>)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
     * followed by one or more decimal digits.  The value of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
     * exponent must lie between -{@link Integer#MAX_VALUE} ({@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
     * Integer#MIN_VALUE}+1) and {@link Integer#MAX_VALUE}, inclusive.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
     * <p>More formally, the strings this constructor accepts are
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
     * described by the following grammar:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
     * <blockquote>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
     * <dl>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
     * <dt><i>BigDecimalString:</i>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
     * <dd><i>Sign<sub>opt</sub> Significand Exponent<sub>opt</sub></i>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
     * <dt><i>Sign:</i>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
     * <dd>{@code +}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
     * <dd>{@code -}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
     * <dt><i>Significand:</i>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
     * <dd><i>IntegerPart</i> {@code .} <i>FractionPart<sub>opt</sub></i>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
     * <dd>{@code .} <i>FractionPart</i>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
     * <dd><i>IntegerPart</i>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
     * <dt><i>IntegerPart:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
     * <dd>Digits</i>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
     * <dt><i>FractionPart:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
     * <dd>Digits</i>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
     * <dt><i>Exponent:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
     * <dd>ExponentIndicator SignedInteger</i>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
     * <dt><i>ExponentIndicator:</i>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
     * <dd>{@code e}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
     * <dd>{@code E}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
     * <dt><i>SignedInteger:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
     * <dd>Sign<sub>opt</sub> Digits</i>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
     * <dt><i>Digits:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
     * <dd>Digit
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
     * <dd>Digits Digit</i>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
     * <dt><i>Digit:</i>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
     * <dd>any character for which {@link Character#isDigit}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
     * returns {@code true}, including 0, 1, 2 ...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
     * </dl>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
     * </blockquote>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
     * <p>The scale of the returned {@code BigDecimal} will be the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
     * number of digits in the fraction, or zero if the string
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
     * contains no decimal point, subject to adjustment for any
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
     * exponent; if the string contains an exponent, the exponent is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
     * subtracted from the scale.  The value of the resulting scale
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
     * must lie between {@code Integer.MIN_VALUE} and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
     * {@code Integer.MAX_VALUE}, inclusive.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
     * <p>The character-to-digit mapping is provided by {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
     * java.lang.Character#digit} set to convert to radix 10.  The
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
     * String may not contain any extraneous characters (whitespace,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
     * for example).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
     * <p><b>Examples:</b><br>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
     * The value of the returned {@code BigDecimal} is equal to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
     * <i>significand</i> &times; 10<sup>&nbsp;<i>exponent</i></sup>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
     * For each string on the left, the resulting representation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
     * [{@code BigInteger}, {@code scale}] is shown on the right.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
     * <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
     * "0"            [0,0]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
     * "0.00"         [0,2]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
     * "123"          [123,0]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
     * "-123"         [-123,0]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
     * "1.23E3"       [123,-1]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
     * "1.23E+3"      [123,-1]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
     * "12.3E+7"      [123,-6]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
     * "12.0"         [120,1]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
     * "12.3"         [123,1]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
     * "0.00123"      [123,5]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
     * "-1.23E-12"    [-123,14]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
     * "1234.5E-4"    [12345,5]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
     * "0E+7"         [0,-7]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
     * "-0"           [0,0]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
     * </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
     * <p>Note: For values other than {@code float} and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
     * {@code double} NaN and &plusmn;Infinity, this constructor is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
     * compatible with the values returned by {@link Float#toString}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
     * and {@link Double#toString}.  This is generally the preferred
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
     * way to convert a {@code float} or {@code double} into a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
     * BigDecimal, as it doesn't suffer from the unpredictability of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
     * the {@link #BigDecimal(double)} constructor.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
     * @param val String representation of {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
     * @throws NumberFormatException if {@code val} is not a valid
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
     *         representation of a {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
    public BigDecimal(String val) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
        this(val.toCharArray(), 0, val.length());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
     * Translates the string representation of a {@code BigDecimal}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
     * into a {@code BigDecimal}, accepting the same strings as the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
     * {@link #BigDecimal(String)} constructor, with rounding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
     * according to the context settings.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
     * @param  val string representation of a {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
     * @param  mc the context to use.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
     * @throws ArithmeticException if the result is inexact but the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
     *         rounding mode is {@code UNNECESSARY}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
     * @throws NumberFormatException if {@code val} is not a valid
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
     *         representation of a BigDecimal.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
    public BigDecimal(String val, MathContext mc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
        this(val.toCharArray(), 0, val.length());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
        if (mc.precision > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
            roundThis(mc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
     * Translates a {@code double} into a {@code BigDecimal} which
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
     * is the exact decimal representation of the {@code double}'s
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
     * binary floating-point value.  The scale of the returned
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
     * {@code BigDecimal} is the smallest value such that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
     * <tt>(10<sup>scale</sup> &times; val)</tt> is an integer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
     * <b>Notes:</b>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
     * <ol>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
     * <li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
     * The results of this constructor can be somewhat unpredictable.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
     * One might assume that writing {@code new BigDecimal(0.1)} in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
     * Java creates a {@code BigDecimal} which is exactly equal to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
     * 0.1 (an unscaled value of 1, with a scale of 1), but it is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
     * actually equal to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
     * 0.1000000000000000055511151231257827021181583404541015625.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
     * This is because 0.1 cannot be represented exactly as a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
     * {@code double} (or, for that matter, as a binary fraction of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
     * any finite length).  Thus, the value that is being passed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
     * <i>in</i> to the constructor is not exactly equal to 0.1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
     * appearances notwithstanding.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
     * <li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
     * The {@code String} constructor, on the other hand, is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
     * perfectly predictable: writing {@code new BigDecimal("0.1")}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
     * creates a {@code BigDecimal} which is <i>exactly</i> equal to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
     * 0.1, as one would expect.  Therefore, it is generally
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
     * recommended that the {@linkplain #BigDecimal(String)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
     * <tt>String</tt> constructor} be used in preference to this one.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
     * <li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
     * When a {@code double} must be used as a source for a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
     * {@code BigDecimal}, note that this constructor provides an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
     * exact conversion; it does not give the same result as
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
     * converting the {@code double} to a {@code String} using the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
     * {@link Double#toString(double)} method and then using the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
     * {@link #BigDecimal(String)} constructor.  To get that result,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
     * use the {@code static} {@link #valueOf(double)} method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
     * </ol>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
     * @param val {@code double} value to be converted to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
     *        {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
     * @throws NumberFormatException if {@code val} is infinite or NaN.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
    public BigDecimal(double val) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
        if (Double.isInfinite(val) || Double.isNaN(val))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
            throw new NumberFormatException("Infinite or NaN");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
        // Translate the double into sign, exponent and significand, according
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
        // to the formulae in JLS, Section 20.10.22.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
        long valBits = Double.doubleToLongBits(val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
        int sign = ((valBits >> 63)==0 ? 1 : -1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
        int exponent = (int) ((valBits >> 52) & 0x7ffL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
        long significand = (exponent==0 ? (valBits & ((1L<<52) - 1)) << 1
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
                            : (valBits & ((1L<<52) - 1)) | (1L<<52));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
        exponent -= 1075;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
        // At this point, val == sign * significand * 2**exponent.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
         * Special case zero to supress nonterminating normalization
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
         * and bogus scale calculation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
        if (significand == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
            intVal = BigInteger.ZERO;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
            intCompact = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
            precision = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
        // Normalize
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
        while((significand & 1) == 0) {    //  i.e., significand is even
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
            significand >>= 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
            exponent++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
        // Calculate intVal and scale
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
        intVal = BigInteger.valueOf(sign*significand);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
        if (exponent < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
            intVal = intVal.multiply(BigInteger.valueOf(5).pow(-exponent));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
            scale = -exponent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
        } else if (exponent > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
            intVal = intVal.multiply(BigInteger.valueOf(2).pow(exponent));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
        if (intVal.bitLength() <= MAX_BIGINT_BITS) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
            intCompact = intVal.longValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
     * Translates a {@code double} into a {@code BigDecimal}, with
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
     * rounding according to the context settings.  The scale of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
     * {@code BigDecimal} is the smallest value such that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
     * <tt>(10<sup>scale</sup> &times; val)</tt> is an integer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
     * <p>The results of this constructor can be somewhat unpredictable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
     * and its use is generally not recommended; see the notes under
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
     * the {@link #BigDecimal(double)} constructor.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
     * @param  val {@code double} value to be converted to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
     *         {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
     * @param  mc the context to use.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
     * @throws ArithmeticException if the result is inexact but the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
     *         RoundingMode is UNNECESSARY.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
     * @throws NumberFormatException if {@code val} is infinite or NaN.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
    public BigDecimal(double val, MathContext mc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
        this(val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
        if (mc.precision > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
            roundThis(mc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
     * Translates a {@code BigInteger} into a {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
     * The scale of the {@code BigDecimal} is zero.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
     * @param val {@code BigInteger} value to be converted to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
     *            {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
    public BigDecimal(BigInteger val) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
        intVal = val;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
        if (val.bitLength() <= MAX_BIGINT_BITS) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
            intCompact = val.longValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
     * Translates a {@code BigInteger} into a {@code BigDecimal}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
     * rounding according to the context settings.  The scale of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
     * {@code BigDecimal} is zero.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
     * @param val {@code BigInteger} value to be converted to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
     *            {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
     * @param  mc the context to use.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
     * @throws ArithmeticException if the result is inexact but the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
     *         rounding mode is {@code UNNECESSARY}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
    public BigDecimal(BigInteger val, MathContext mc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
        intVal = val;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
        if (mc.precision > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
            roundThis(mc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
     * Translates a {@code BigInteger} unscaled value and an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
     * {@code int} scale into a {@code BigDecimal}.  The value of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
     * the {@code BigDecimal} is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
     * <tt>(unscaledVal &times; 10<sup>-scale</sup>)</tt>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
     * @param unscaledVal unscaled value of the {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
     * @param scale scale of the {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
    public BigDecimal(BigInteger unscaledVal, int scale) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
        // Negative scales are now allowed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
        intVal = unscaledVal;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
        this.scale = scale;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
        if (unscaledVal.bitLength() <= MAX_BIGINT_BITS) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
            intCompact = unscaledVal.longValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
     * Translates a {@code BigInteger} unscaled value and an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
     * {@code int} scale into a {@code BigDecimal}, with rounding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
     * according to the context settings.  The value of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
     * {@code BigDecimal} is <tt>(unscaledVal &times;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
     * 10<sup>-scale</sup>)</tt>, rounded according to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
     * {@code precision} and rounding mode settings.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
     * @param  unscaledVal unscaled value of the {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
     * @param  scale scale of the {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
     * @param  mc the context to use.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
     * @throws ArithmeticException if the result is inexact but the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
     *         rounding mode is {@code UNNECESSARY}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
    public BigDecimal(BigInteger unscaledVal, int scale, MathContext mc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
        intVal = unscaledVal;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
        this.scale = scale;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
        if (mc.precision > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
            roundThis(mc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
     * Translates an {@code int} into a {@code BigDecimal}.  The
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
     * scale of the {@code BigDecimal} is zero.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
     * @param val {@code int} value to be converted to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
     *            {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
    public BigDecimal(int val) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
        intCompact = val;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
     * Translates an {@code int} into a {@code BigDecimal}, with
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
     * rounding according to the context settings.  The scale of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
     * {@code BigDecimal}, before any rounding, is zero.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
     * @param  val {@code int} value to be converted to {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
     * @param  mc the context to use.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
     * @throws ArithmeticException if the result is inexact but the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
     *         rounding mode is {@code UNNECESSARY}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
    public BigDecimal(int val, MathContext mc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
        intCompact = val;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
        if (mc.precision > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
            roundThis(mc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
     * Translates a {@code long} into a {@code BigDecimal}.  The
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
     * scale of the {@code BigDecimal} is zero.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
     * @param val {@code long} value to be converted to {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
    public BigDecimal(long val) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
        if (compactLong(val))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
            intCompact = val;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
        else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
            intVal = BigInteger.valueOf(val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
90ce3da70b43 Initial load
duke
parents:
diff changeset
   908
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
     * Translates a {@code long} into a {@code BigDecimal}, with
90ce3da70b43 Initial load
duke
parents:
diff changeset
   910
     * rounding according to the context settings.  The scale of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
     * {@code BigDecimal}, before any rounding, is zero.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
     * @param  val {@code long} value to be converted to {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   914
     * @param  mc the context to use.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
     * @throws ArithmeticException if the result is inexact but the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   916
     *         rounding mode is {@code UNNECESSARY}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
    public BigDecimal(long val, MathContext mc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
        if (compactLong(val))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
            intCompact = val;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
        else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
            intVal = BigInteger.valueOf(val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
        if (mc.precision > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
            roundThis(mc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   926
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
     * Trusted internal constructor
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
    private BigDecimal(long val, int scale) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
        this.intCompact = val;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
        this.scale = scale;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
90ce3da70b43 Initial load
duke
parents:
diff changeset
   936
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   937
     * Trusted internal constructor
90ce3da70b43 Initial load
duke
parents:
diff changeset
   938
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   939
    private BigDecimal(BigInteger intVal, long val, int scale) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
        this.intVal = intVal;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   941
        this.intCompact = val;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
        this.scale = scale;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   943
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   944
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
    // Static Factory Methods
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
     * Translates a {@code long} unscaled value and an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
     * {@code int} scale into a {@code BigDecimal}.  This
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
     * {@literal "static factory method"} is provided in preference to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
     * a ({@code long}, {@code int}) constructor because it
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
     * allows for reuse of frequently used {@code BigDecimal} values..
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   954
     * @param unscaledVal unscaled value of the {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   955
     * @param scale scale of the {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   956
     * @return a {@code BigDecimal} whose value is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   957
     *         <tt>(unscaledVal &times; 10<sup>-scale</sup>)</tt>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   958
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   959
    public static BigDecimal valueOf(long unscaledVal, int scale) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   960
        if (scale == 0 && unscaledVal >= 0 && unscaledVal <= 10) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   961
            return zeroThroughTen[(int)unscaledVal];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   962
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   963
        if (compactLong(unscaledVal))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   964
            return new BigDecimal(unscaledVal, scale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   965
        return new BigDecimal(BigInteger.valueOf(unscaledVal), scale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   967
90ce3da70b43 Initial load
duke
parents:
diff changeset
   968
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   969
     * Translates a {@code long} value into a {@code BigDecimal}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   970
     * with a scale of zero.  This {@literal "static factory method"}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   971
     * is provided in preference to a ({@code long}) constructor
90ce3da70b43 Initial load
duke
parents:
diff changeset
   972
     * because it allows for reuse of frequently used
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
     * {@code BigDecimal} values.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   974
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   975
     * @param val value of the {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   976
     * @return a {@code BigDecimal} whose value is {@code val}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   977
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   978
    public static BigDecimal valueOf(long val) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   979
        return valueOf(val, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   980
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   981
90ce3da70b43 Initial load
duke
parents:
diff changeset
   982
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   983
     * Translates a {@code double} into a {@code BigDecimal}, using
90ce3da70b43 Initial load
duke
parents:
diff changeset
   984
     * the {@code double}'s canonical string representation provided
90ce3da70b43 Initial load
duke
parents:
diff changeset
   985
     * by the {@link Double#toString(double)} method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   986
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   987
     * <p><b>Note:</b> This is generally the preferred way to convert
90ce3da70b43 Initial load
duke
parents:
diff changeset
   988
     * a {@code double} (or {@code float}) into a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   989
     * {@code BigDecimal}, as the value returned is equal to that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   990
     * resulting from constructing a {@code BigDecimal} from the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   991
     * result of using {@link Double#toString(double)}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   992
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   993
     * @param  val {@code double} to convert to a {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   994
     * @return a {@code BigDecimal} whose value is equal to or approximately
90ce3da70b43 Initial load
duke
parents:
diff changeset
   995
     *         equal to the value of {@code val}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   996
     * @throws NumberFormatException if {@code val} is infinite or NaN.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   997
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
   998
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
    public static BigDecimal valueOf(double val) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
        // Reminder: a zero double returns '0.0', so we cannot fastpath
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1001
        // to use the constant ZERO.  This might be important enough to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1002
        // justify a factory approach, a cache, or a few private
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
        // constants, later.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1004
        return new BigDecimal(Double.toString(val));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1005
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1006
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1007
    // Arithmetic Operations
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1008
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1009
     * Returns a {@code BigDecimal} whose value is {@code (this +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1010
     * augend)}, and whose scale is {@code max(this.scale(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1011
     * augend.scale())}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1012
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1013
     * @param  augend value to be added to this {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1014
     * @return {@code this + augend}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1016
    public BigDecimal add(BigDecimal augend) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1017
        BigDecimal arg[] = {this, augend};
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1018
        matchScale(arg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1019
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1020
        long x = arg[0].intCompact;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1021
        long y = arg[1].intCompact;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1022
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
        // Might be able to do a more clever check incorporating the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1024
        // inflated check into the overflow computation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
        if (x != INFLATED && y != INFLATED) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
            long sum = x + y;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1027
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1028
             * If the sum is not an overflowed value, continue to use
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1029
             * the compact representation.  if either of x or y is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1030
             * INFLATED, the sum should also be regarded as an
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1031
             * overflow.  See "Hacker's Delight" section 2-12 for
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
             * explanation of the overflow test.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1034
            if ( (((sum ^ x) & (sum ^ y)) >> 63) == 0L )        // not overflowed
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1035
                return BigDecimal.valueOf(sum, arg[0].scale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1036
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1037
        return new BigDecimal(arg[0].inflate().intVal.add(arg[1].inflate().intVal), arg[0].scale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1038
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1039
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1040
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1041
     * Returns a {@code BigDecimal} whose value is {@code (this + augend)},
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1042
     * with rounding according to the context settings.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1043
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1044
     * If either number is zero and the precision setting is nonzero then
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1045
     * the other number, rounded if necessary, is used as the result.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1046
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1047
     * @param  augend value to be added to this {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1048
     * @param  mc the context to use.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1049
     * @return {@code this + augend}, rounded as necessary.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1050
     * @throws ArithmeticException if the result is inexact but the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1051
     *         rounding mode is {@code UNNECESSARY}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1052
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1053
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1054
    public BigDecimal add(BigDecimal augend, MathContext mc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1055
        if (mc.precision == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1056
            return add(augend);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1057
        BigDecimal lhs = this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1058
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1059
        // Could optimize if values are compact
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1060
        this.inflate();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1061
        augend.inflate();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1062
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1063
        // If either number is zero then the other number, rounded and
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1064
        // scaled if necessary, is used as the result.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1065
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1066
            boolean lhsIsZero = lhs.signum() == 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1067
            boolean augendIsZero = augend.signum() == 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1068
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1069
            if (lhsIsZero || augendIsZero) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1070
                int preferredScale = Math.max(lhs.scale(), augend.scale());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1071
                BigDecimal result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1072
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1073
                // Could use a factory for zero instead of a new object
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1074
                if (lhsIsZero && augendIsZero)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1075
                    return new BigDecimal(BigInteger.ZERO, 0, preferredScale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1076
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1077
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1078
                result = lhsIsZero ? augend.doRound(mc) : lhs.doRound(mc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1079
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1080
                if (result.scale() == preferredScale)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1081
                    return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1082
                else if (result.scale() > preferredScale)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1083
                    return new BigDecimal(result.intVal, result.intCompact, result.scale).
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1084
                        stripZerosToMatchScale(preferredScale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1085
                else { // result.scale < preferredScale
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1086
                    int precisionDiff = mc.precision - result.precision();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1087
                    int scaleDiff     = preferredScale - result.scale();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1088
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1089
                    if (precisionDiff >= scaleDiff)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1090
                        return result.setScale(preferredScale); // can achieve target scale
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1091
                    else
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1092
                        return result.setScale(result.scale() + precisionDiff);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1093
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1094
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1095
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1096
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1097
        long padding = (long)lhs.scale - augend.scale;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1098
        if (padding != 0) {        // scales differ; alignment needed
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1099
            BigDecimal arg[] = preAlign(lhs, augend, padding, mc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1100
            matchScale(arg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1101
            lhs    = arg[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1102
            augend = arg[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1103
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1104
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1105
        return new BigDecimal(lhs.inflate().intVal.add(augend.inflate().intVal),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1106
                              lhs.scale).doRound(mc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1107
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1108
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1109
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1110
     * Returns an array of length two, the sum of whose entries is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1111
     * equal to the rounded sum of the {@code BigDecimal} arguments.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1112
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1113
     * <p>If the digit positions of the arguments have a sufficient
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1114
     * gap between them, the value smaller in magnitude can be
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1115
     * condensed into a {@literal "sticky bit"} and the end result will
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1116
     * round the same way <em>if</em> the precision of the final
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1117
     * result does not include the high order digit of the small
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1118
     * magnitude operand.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1119
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1120
     * <p>Note that while strictly speaking this is an optimization,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1121
     * it makes a much wider range of additions practical.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1122
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1123
     * <p>This corresponds to a pre-shift operation in a fixed
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1124
     * precision floating-point adder; this method is complicated by
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1125
     * variable precision of the result as determined by the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1126
     * MathContext.  A more nuanced operation could implement a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1127
     * {@literal "right shift"} on the smaller magnitude operand so
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1128
     * that the number of digits of the smaller operand could be
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1129
     * reduced even though the significands partially overlapped.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1130
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1131
    private BigDecimal[] preAlign(BigDecimal lhs, BigDecimal augend,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1132
                                  long padding, MathContext mc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1133
        assert padding != 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1134
        BigDecimal big;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1135
        BigDecimal small;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1136
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1137
        if (padding < 0) {     // lhs is big;   augend is small
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1138
            big   = lhs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1139
            small = augend;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1140
        } else {               // lhs is small; augend is big
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1141
            big   = augend;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1142
            small = lhs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1143
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1144
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1145
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1146
         * This is the estimated scale of an ulp of the result; it
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1147
         * assumes that the result doesn't have a carry-out on a true
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1148
         * add (e.g. 999 + 1 => 1000) or any subtractive cancellation
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1149
         * on borrowing (e.g. 100 - 1.2 => 98.8)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1150
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1151
        long estResultUlpScale = (long)big.scale - big.precision() + mc.precision;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1152
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1153
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1154
         * The low-order digit position of big is big.scale().  This
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1155
         * is true regardless of whether big has a positive or
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1156
         * negative scale.  The high-order digit position of small is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1157
         * small.scale - (small.precision() - 1).  To do the full
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1158
         * condensation, the digit positions of big and small must be
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1159
         * disjoint *and* the digit positions of small should not be
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1160
         * directly visible in the result.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1161
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1162
        long smallHighDigitPos = (long)small.scale - small.precision() + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1163
        if (smallHighDigitPos > big.scale + 2 &&         // big and small disjoint
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1164
            smallHighDigitPos > estResultUlpScale + 2) { // small digits not visible
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1165
            small = BigDecimal.valueOf(small.signum(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1166
                                       this.checkScale(Math.max(big.scale, estResultUlpScale) + 3));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1167
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1168
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1169
        // Since addition is symmetric, preserving input order in
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1170
        // returned operands doesn't matter
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1171
        BigDecimal[] result = {big, small};
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1172
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1173
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1174
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1175
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1176
     * Returns a {@code BigDecimal} whose value is {@code (this -
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1177
     * subtrahend)}, and whose scale is {@code max(this.scale(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1178
     * subtrahend.scale())}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1179
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1180
     * @param  subtrahend value to be subtracted from this {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1181
     * @return {@code this - subtrahend}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1182
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1183
    public BigDecimal subtract(BigDecimal subtrahend) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1184
        BigDecimal arg[] = {this, subtrahend};
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1185
        matchScale(arg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1186
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1187
        long x = arg[0].intCompact;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1188
        long y = arg[1].intCompact;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1189
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1190
        // Might be able to do a more clever check incorporating the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1191
        // inflated check into the overflow computation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1192
        if (x != INFLATED && y != INFLATED) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1193
            long difference = x - y;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1194
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1195
             * If the difference is not an overflowed value, continue
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1196
             * to use the compact representation.  if either of x or y
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1197
             * is INFLATED, the difference should also be regarded as
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1198
             * an overflow.  See "Hacker's Delight" section 2-12 for
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1199
             * explanation of the overflow test.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1200
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1201
            if ( ((x ^ y) & (difference ^ x) ) >> 63 == 0L )    // not overflowed
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1202
                return BigDecimal.valueOf(difference, arg[0].scale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1203
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1204
        return new BigDecimal(arg[0].inflate().intVal.subtract(arg[1].inflate().intVal),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1205
                              arg[0].scale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1206
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1207
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1208
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1209
     * Returns a {@code BigDecimal} whose value is {@code (this - subtrahend)},
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1210
     * with rounding according to the context settings.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1211
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1212
     * If {@code subtrahend} is zero then this, rounded if necessary, is used as the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1213
     * result.  If this is zero then the result is {@code subtrahend.negate(mc)}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1214
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1215
     * @param  subtrahend value to be subtracted from this {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1216
     * @param  mc the context to use.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1217
     * @return {@code this - subtrahend}, rounded as necessary.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1218
     * @throws ArithmeticException if the result is inexact but the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1219
     *         rounding mode is {@code UNNECESSARY}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1220
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1221
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1222
    public BigDecimal subtract(BigDecimal subtrahend, MathContext mc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1223
        if (mc.precision == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1224
            return subtract(subtrahend);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1225
        // share the special rounding code in add()
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1226
        this.inflate();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1227
        subtrahend.inflate();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1228
        BigDecimal rhs = new BigDecimal(subtrahend.intVal.negate(), subtrahend.scale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1229
        rhs.precision = subtrahend.precision;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1230
        return add(rhs, mc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1231
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1232
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1233
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1234
     * Returns a {@code BigDecimal} whose value is <tt>(this &times;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1235
     * multiplicand)</tt>, and whose scale is {@code (this.scale() +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1236
     * multiplicand.scale())}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1237
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1238
     * @param  multiplicand value to be multiplied by this {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1239
     * @return {@code this * multiplicand}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1240
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1241
    public BigDecimal multiply(BigDecimal multiplicand) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1242
        long x = this.intCompact;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1243
        long y = multiplicand.intCompact;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1244
        int productScale = checkScale((long)scale+multiplicand.scale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1245
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1246
        // Might be able to do a more clever check incorporating the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1247
        // inflated check into the overflow computation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1248
        if (x != INFLATED && y != INFLATED) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1249
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1250
             * If the product is not an overflowed value, continue
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1251
             * to use the compact representation.  if either of x or y
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1252
             * is INFLATED, the product should also be regarded as
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1253
             * an overflow.  See "Hacker's Delight" section 2-12 for
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1254
             * explanation of the overflow test.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1255
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1256
            long product = x * y;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1257
            if ( !(y != 0L && product/y != x)  )        // not overflowed
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1258
                return BigDecimal.valueOf(product, productScale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1259
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1260
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1261
        BigDecimal result = new BigDecimal(this.inflate().intVal.multiply(multiplicand.inflate().intVal), productScale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1262
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1263
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1264
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1265
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1266
     * Returns a {@code BigDecimal} whose value is <tt>(this &times;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1267
     * multiplicand)</tt>, with rounding according to the context settings.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1268
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1269
     * @param  multiplicand value to be multiplied by this {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1270
     * @param  mc the context to use.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1271
     * @return {@code this * multiplicand}, rounded as necessary.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1272
     * @throws ArithmeticException if the result is inexact but the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1273
     *         rounding mode is {@code UNNECESSARY}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1274
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1275
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1276
    public BigDecimal multiply(BigDecimal multiplicand, MathContext mc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1277
        if (mc.precision == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1278
            return multiply(multiplicand);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1279
        BigDecimal lhs = this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1280
        return lhs.inflate().multiply(multiplicand.inflate()).doRound(mc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1281
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1282
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1283
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1284
     * Returns a {@code BigDecimal} whose value is {@code (this /
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1285
     * divisor)}, and whose scale is as specified.  If rounding must
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1286
     * be performed to generate a result with the specified scale, the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1287
     * specified rounding mode is applied.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1288
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1289
     * <p>The new {@link #divide(BigDecimal, int, RoundingMode)} method
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1290
     * should be used in preference to this legacy method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1291
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1292
     * @param  divisor value by which this {@code BigDecimal} is to be divided.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1293
     * @param  scale scale of the {@code BigDecimal} quotient to be returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1294
     * @param  roundingMode rounding mode to apply.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1295
     * @return {@code this / divisor}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1296
     * @throws ArithmeticException if {@code divisor} is zero,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1297
     *         {@code roundingMode==ROUND_UNNECESSARY} and
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1298
     *         the specified scale is insufficient to represent the result
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1299
     *         of the division exactly.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1300
     * @throws IllegalArgumentException if {@code roundingMode} does not
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1301
     *         represent a valid rounding mode.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1302
     * @see    #ROUND_UP
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1303
     * @see    #ROUND_DOWN
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1304
     * @see    #ROUND_CEILING
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1305
     * @see    #ROUND_FLOOR
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1306
     * @see    #ROUND_HALF_UP
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1307
     * @see    #ROUND_HALF_DOWN
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1308
     * @see    #ROUND_HALF_EVEN
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1309
     * @see    #ROUND_UNNECESSARY
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1310
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1311
    public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1312
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1313
         * IMPLEMENTATION NOTE: This method *must* return a new object
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1314
         * since dropDigits uses divide to generate a value whose
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1315
         * scale is then modified.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1316
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1317
        if (roundingMode < ROUND_UP || roundingMode > ROUND_UNNECESSARY)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1318
            throw new IllegalArgumentException("Invalid rounding mode");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1319
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1320
         * Rescale dividend or divisor (whichever can be "upscaled" to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1321
         * produce correctly scaled quotient).
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1322
         * Take care to detect out-of-range scales
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1323
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1324
        BigDecimal dividend;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1325
        if (checkScale((long)scale + divisor.scale) >= this.scale) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1326
            dividend = this.setScale(scale + divisor.scale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1327
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1328
            dividend = this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1329
            divisor = divisor.setScale(checkScale((long)this.scale - scale));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1330
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1331
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1332
        boolean compact = dividend.intCompact != INFLATED && divisor.intCompact != INFLATED;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1333
        long div = INFLATED;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1334
        long rem = INFLATED;;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1335
        BigInteger q=null, r=null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1336
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1337
        if (compact) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1338
            div = dividend.intCompact / divisor.intCompact;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1339
            rem = dividend.intCompact % divisor.intCompact;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1340
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1341
            // Do the division and return result if it's exact.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1342
            BigInteger i[] = dividend.inflate().intVal.divideAndRemainder(divisor.inflate().intVal);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1343
            q = i[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1344
            r = i[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1345
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1346
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1347
        // Check for exact result
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1348
        if (compact) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1349
            if (rem == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1350
                return new BigDecimal(div, scale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1351
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1352
            if (r.signum() == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1353
                return new BigDecimal(q, scale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1354
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1355
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1356
        if (roundingMode == ROUND_UNNECESSARY)      // Rounding prohibited
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1357
            throw new ArithmeticException("Rounding necessary");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1358
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1359
        /* Round as appropriate */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1360
        int signum = dividend.signum() * divisor.signum(); // Sign of result
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1361
        boolean increment;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1362
        if (roundingMode == ROUND_UP) {             // Away from zero
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1363
            increment = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1364
        } else if (roundingMode == ROUND_DOWN) {    // Towards zero
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1365
            increment = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1366
        } else if (roundingMode == ROUND_CEILING) { // Towards +infinity
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1367
            increment = (signum > 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1368
        } else if (roundingMode == ROUND_FLOOR) {   // Towards -infinity
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1369
            increment = (signum < 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1370
        } else { // Remaining modes based on nearest-neighbor determination
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1371
            int cmpFracHalf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1372
            if (compact) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1373
                 cmpFracHalf = longCompareTo(Math.abs(2*rem), Math.abs(divisor.intCompact));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1374
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1375
                // add(r) here is faster than multiply(2) or shiftLeft(1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1376
                cmpFracHalf= r.add(r).abs().compareTo(divisor.intVal.abs());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1377
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1378
            if (cmpFracHalf < 0) {         // We're closer to higher digit
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1379
                increment = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1380
            } else if (cmpFracHalf > 0) {  // We're closer to lower digit
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1381
                increment = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1382
            } else {                       // We're dead-center
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1383
                if (roundingMode == ROUND_HALF_UP)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1384
                    increment = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1385
                else if (roundingMode == ROUND_HALF_DOWN)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1386
                    increment = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1387
                else { // roundingMode == ROUND_HALF_EVEN
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1388
                    if (compact)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1389
                        increment = (div & 1L) != 0L;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1390
                    else
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1391
                        increment = q.testBit(0);   // true iff q is odd
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1392
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1393
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1394
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1395
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1396
        if (compact) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1397
            if (increment)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1398
                div += signum; // guaranteed not to overflow
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1399
            return new BigDecimal(div, scale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1400
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1401
            return (increment
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1402
                    ? new BigDecimal(q.add(BigInteger.valueOf(signum)), scale)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1403
                    : new BigDecimal(q, scale));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1404
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1405
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1406
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1407
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1408
     * Returns a {@code BigDecimal} whose value is {@code (this /
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1409
     * divisor)}, and whose scale is as specified.  If rounding must
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1410
     * be performed to generate a result with the specified scale, the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1411
     * specified rounding mode is applied.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1412
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1413
     * @param  divisor value by which this {@code BigDecimal} is to be divided.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1414
     * @param  scale scale of the {@code BigDecimal} quotient to be returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1415
     * @param  roundingMode rounding mode to apply.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1416
     * @return {@code this / divisor}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1417
     * @throws ArithmeticException if {@code divisor} is zero,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1418
     *         {@code roundingMode==RoundingMode.UNNECESSARY} and
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1419
     *         the specified scale is insufficient to represent the result
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1420
     *         of the division exactly.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1421
     * @since 1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1422
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1423
    public BigDecimal divide(BigDecimal divisor, int scale, RoundingMode roundingMode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1424
        return divide(divisor, scale, roundingMode.oldMode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1425
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1426
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1427
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1428
     * Returns a {@code BigDecimal} whose value is {@code (this /
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1429
     * divisor)}, and whose scale is {@code this.scale()}.  If
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1430
     * rounding must be performed to generate a result with the given
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1431
     * scale, the specified rounding mode is applied.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1432
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1433
     * <p>The new {@link #divide(BigDecimal, RoundingMode)} method
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1434
     * should be used in preference to this legacy method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1435
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1436
     * @param  divisor value by which this {@code BigDecimal} is to be divided.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1437
     * @param  roundingMode rounding mode to apply.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1438
     * @return {@code this / divisor}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1439
     * @throws ArithmeticException if {@code divisor==0}, or
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1440
     *         {@code roundingMode==ROUND_UNNECESSARY} and
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1441
     *         {@code this.scale()} is insufficient to represent the result
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1442
     *         of the division exactly.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1443
     * @throws IllegalArgumentException if {@code roundingMode} does not
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1444
     *         represent a valid rounding mode.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1445
     * @see    #ROUND_UP
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1446
     * @see    #ROUND_DOWN
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1447
     * @see    #ROUND_CEILING
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1448
     * @see    #ROUND_FLOOR
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1449
     * @see    #ROUND_HALF_UP
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1450
     * @see    #ROUND_HALF_DOWN
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1451
     * @see    #ROUND_HALF_EVEN
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1452
     * @see    #ROUND_UNNECESSARY
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1453
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1454
    public BigDecimal divide(BigDecimal divisor, int roundingMode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1455
            return this.divide(divisor, scale, roundingMode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1456
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1457
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1458
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1459
     * Returns a {@code BigDecimal} whose value is {@code (this /
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1460
     * divisor)}, and whose scale is {@code this.scale()}.  If
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1461
     * rounding must be performed to generate a result with the given
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1462
     * scale, the specified rounding mode is applied.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1463
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1464
     * @param  divisor value by which this {@code BigDecimal} is to be divided.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1465
     * @param  roundingMode rounding mode to apply.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1466
     * @return {@code this / divisor}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1467
     * @throws ArithmeticException if {@code divisor==0}, or
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1468
     *         {@code roundingMode==RoundingMode.UNNECESSARY} and
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1469
     *         {@code this.scale()} is insufficient to represent the result
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1470
     *         of the division exactly.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1471
     * @since 1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1472
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1473
    public BigDecimal divide(BigDecimal divisor, RoundingMode roundingMode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1474
        return this.divide(divisor, scale, roundingMode.oldMode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1475
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1476
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1477
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1478
     * Returns a {@code BigDecimal} whose value is {@code (this /
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1479
     * divisor)}, and whose preferred scale is {@code (this.scale() -
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1480
     * divisor.scale())}; if the exact quotient cannot be
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1481
     * represented (because it has a non-terminating decimal
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1482
     * expansion) an {@code ArithmeticException} is thrown.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1483
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1484
     * @param  divisor value by which this {@code BigDecimal} is to be divided.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1485
     * @throws ArithmeticException if the exact quotient does not have a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1486
     *         terminating decimal expansion
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1487
     * @return {@code this / divisor}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1488
     * @since 1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1489
     * @author Joseph D. Darcy
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1490
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1491
    public BigDecimal divide(BigDecimal divisor) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1492
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1493
         * Handle zero cases first.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1494
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1495
        if (divisor.signum() == 0) {   // x/0
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1496
            if (this.signum() == 0)    // 0/0
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1497
                throw new ArithmeticException("Division undefined");  // NaN
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1498
            throw new ArithmeticException("Division by zero");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1499
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1500
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1501
        // Calculate preferred scale
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1502
        int preferredScale = (int)Math.max(Math.min((long)this.scale() - divisor.scale(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1503
                                                    Integer.MAX_VALUE), Integer.MIN_VALUE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1504
        if (this.signum() == 0)        // 0/y
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1505
            return new BigDecimal(0, preferredScale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1506
        else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1507
            this.inflate();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1508
            divisor.inflate();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1509
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1510
             * If the quotient this/divisor has a terminating decimal
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1511
             * expansion, the expansion can have no more than
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1512
             * (a.precision() + ceil(10*b.precision)/3) digits.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1513
             * Therefore, create a MathContext object with this
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1514
             * precision and do a divide with the UNNECESSARY rounding
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1515
             * mode.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1516
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1517
            MathContext mc = new MathContext( (int)Math.min(this.precision() +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1518
                                                            (long)Math.ceil(10.0*divisor.precision()/3.0),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1519
                                                            Integer.MAX_VALUE),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1520
                                              RoundingMode.UNNECESSARY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1521
            BigDecimal quotient;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1522
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1523
                quotient = this.divide(divisor, mc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1524
            } catch (ArithmeticException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1525
                throw new ArithmeticException("Non-terminating decimal expansion; " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1526
                                              "no exact representable decimal result.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1527
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1528
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1529
            int quotientScale = quotient.scale();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1530
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1531
            // divide(BigDecimal, mc) tries to adjust the quotient to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1532
            // the desired one by removing trailing zeros; since the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1533
            // exact divide method does not have an explicit digit
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1534
            // limit, we can add zeros too.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1535
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1536
            if (preferredScale > quotientScale)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1537
                return quotient.setScale(preferredScale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1538
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1539
            return quotient;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1540
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1541
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1542
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1543
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1544
     * Returns a {@code BigDecimal} whose value is {@code (this /
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1545
     * divisor)}, with rounding according to the context settings.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1546
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1547
     * @param  divisor value by which this {@code BigDecimal} is to be divided.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1548
     * @param  mc the context to use.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1549
     * @return {@code this / divisor}, rounded as necessary.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1550
     * @throws ArithmeticException if the result is inexact but the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1551
     *         rounding mode is {@code UNNECESSARY} or
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1552
     *         {@code mc.precision == 0} and the quotient has a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1553
     *         non-terminating decimal expansion.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1554
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1555
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1556
    public BigDecimal divide(BigDecimal divisor, MathContext mc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1557
        if (mc.precision == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1558
            return divide(divisor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1559
        BigDecimal lhs = this.inflate();     // left-hand-side
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1560
        BigDecimal rhs = divisor.inflate();  // right-hand-side
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1561
        BigDecimal result;                   // work
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1562
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1563
        long preferredScale = (long)lhs.scale() - rhs.scale();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1564
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1565
        // Now calculate the answer.  We use the existing
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1566
        // divide-and-round method, but as this rounds to scale we have
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1567
        // to normalize the values here to achieve the desired result.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1568
        // For x/y we first handle y=0 and x=0, and then normalize x and
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1569
        // y to give x' and y' with the following constraints:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1570
        //   (a) 0.1 <= x' < 1
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1571
        //   (b)  x' <= y' < 10*x'
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1572
        // Dividing x'/y' with the required scale set to mc.precision then
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1573
        // will give a result in the range 0.1 to 1 rounded to exactly
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1574
        // the right number of digits (except in the case of a result of
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1575
        // 1.000... which can arise when x=y, or when rounding overflows
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1576
        // The 1.000... case will reduce properly to 1.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1577
        if (rhs.signum() == 0) {      // x/0
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1578
            if (lhs.signum() == 0)    // 0/0
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1579
                throw new ArithmeticException("Division undefined");  // NaN
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1580
            throw new ArithmeticException("Division by zero");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1581
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1582
        if (lhs.signum() == 0)        // 0/y
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1583
            return new BigDecimal(BigInteger.ZERO,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1584
                                  (int)Math.max(Math.min(preferredScale,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1585
                                                         Integer.MAX_VALUE),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1586
                                                Integer.MIN_VALUE));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1587
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1588
        BigDecimal xprime = new BigDecimal(lhs.intVal.abs(), lhs.precision());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1589
        BigDecimal yprime = new BigDecimal(rhs.intVal.abs(), rhs.precision());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1590
        // xprime and yprime are now both in range 0.1 through 0.999...
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1591
        if (mc.roundingMode == RoundingMode.CEILING ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1592
            mc.roundingMode == RoundingMode.FLOOR) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1593
            // The floor (round toward negative infinity) and ceil
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1594
            // (round toward positive infinity) rounding modes are not
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1595
            // invariant under a sign flip.  If xprime/yprime has a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1596
            // different sign than lhs/rhs, the rounding mode must be
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1597
            // changed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1598
            if ((xprime.signum() != lhs.signum()) ^
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1599
                (yprime.signum() != rhs.signum())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1600
                mc = new MathContext(mc.precision,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1601
                                     (mc.roundingMode==RoundingMode.CEILING)?
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1602
                                     RoundingMode.FLOOR:RoundingMode.CEILING);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1603
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1604
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1605
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1606
        if (xprime.compareTo(yprime) > 0)    // satisfy constraint (b)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1607
          yprime.scale -= 1;                 // [that is, yprime *= 10]
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1608
        result = xprime.divide(yprime, mc.precision, mc.roundingMode.oldMode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1609
        // correct the scale of the result...
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1610
        result.scale = checkScale((long)yprime.scale - xprime.scale
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1611
            - (rhs.scale - lhs.scale) + mc.precision);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1612
        // apply the sign
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1613
        if (lhs.signum() != rhs.signum())
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1614
            result = result.negate();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1615
        // doRound, here, only affects 1000000000 case.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1616
        result = result.doRound(mc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1617
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1618
        if (result.multiply(divisor).compareTo(this) == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1619
            // Apply preferred scale rules for exact quotients
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1620
            return result.stripZerosToMatchScale(preferredScale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1621
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1622
        else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1623
            return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1624
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1625
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1626
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1627
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1628
     * Returns a {@code BigDecimal} whose value is the integer part
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1629
     * of the quotient {@code (this / divisor)} rounded down.  The
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1630
     * preferred scale of the result is {@code (this.scale() -
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1631
     * divisor.scale())}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1632
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1633
     * @param  divisor value by which this {@code BigDecimal} is to be divided.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1634
     * @return The integer part of {@code this / divisor}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1635
     * @throws ArithmeticException if {@code divisor==0}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1636
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1637
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1638
    public BigDecimal divideToIntegralValue(BigDecimal divisor) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1639
        // Calculate preferred scale
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1640
        int preferredScale = (int)Math.max(Math.min((long)this.scale() - divisor.scale(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1641
                                                    Integer.MAX_VALUE), Integer.MIN_VALUE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1642
        this.inflate();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1643
        divisor.inflate();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1644
        if (this.abs().compareTo(divisor.abs()) < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1645
            // much faster when this << divisor
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1646
            return BigDecimal.valueOf(0, preferredScale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1647
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1648
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1649
        if(this.signum() == 0 && divisor.signum() != 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1650
            return this.setScale(preferredScale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1651
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1652
        // Perform a divide with enough digits to round to a correct
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1653
        // integer value; then remove any fractional digits
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1654
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1655
        int maxDigits = (int)Math.min(this.precision() +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1656
                                      (long)Math.ceil(10.0*divisor.precision()/3.0) +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1657
                                      Math.abs((long)this.scale() - divisor.scale()) + 2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1658
                                      Integer.MAX_VALUE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1659
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1660
        BigDecimal quotient = this.divide(divisor, new MathContext(maxDigits,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1661
                                                                   RoundingMode.DOWN));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1662
        if (quotient.scale > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1663
            quotient = quotient.setScale(0, RoundingMode.DOWN).
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1664
                stripZerosToMatchScale(preferredScale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1665
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1666
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1667
        if (quotient.scale < preferredScale) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1668
            // pad with zeros if necessary
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1669
            quotient = quotient.setScale(preferredScale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1670
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1671
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1672
        return quotient;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1673
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1674
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1675
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1676
     * Returns a {@code BigDecimal} whose value is the integer part
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1677
     * of {@code (this / divisor)}.  Since the integer part of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1678
     * exact quotient does not depend on the rounding mode, the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1679
     * rounding mode does not affect the values returned by this
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1680
     * method.  The preferred scale of the result is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1681
     * {@code (this.scale() - divisor.scale())}.  An
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1682
     * {@code ArithmeticException} is thrown if the integer part of
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1683
     * the exact quotient needs more than {@code mc.precision}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1684
     * digits.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1685
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1686
     * @param  divisor value by which this {@code BigDecimal} is to be divided.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1687
     * @param  mc the context to use.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1688
     * @return The integer part of {@code this / divisor}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1689
     * @throws ArithmeticException if {@code divisor==0}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1690
     * @throws ArithmeticException if {@code mc.precision} {@literal >} 0 and the result
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1691
     *         requires a precision of more than {@code mc.precision} digits.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1692
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1693
     * @author Joseph D. Darcy
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1694
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1695
    public BigDecimal divideToIntegralValue(BigDecimal divisor, MathContext mc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1696
        if (mc.precision == 0 ||                        // exact result
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1697
            (this.abs().compareTo(divisor.abs()) < 0) ) // zero result
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1698
            return divideToIntegralValue(divisor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1699
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1700
        // Calculate preferred scale
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1701
        int preferredScale = (int)Math.max(Math.min((long)this.scale() - divisor.scale(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1702
                                                    Integer.MAX_VALUE), Integer.MIN_VALUE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1703
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1704
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1705
         * Perform a normal divide to mc.precision digits.  If the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1706
         * remainder has absolute value less than the divisor, the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1707
         * integer portion of the quotient fits into mc.precision
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1708
         * digits.  Next, remove any fractional digits from the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1709
         * quotient and adjust the scale to the preferred value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1710
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1711
        BigDecimal result = this.divide(divisor, new MathContext(mc.precision,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1712
                                                                 RoundingMode.DOWN));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1713
        int resultScale = result.scale();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1714
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1715
        if (result.scale() < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1716
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1717
             * Result is an integer. See if quotient represents the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1718
             * full integer portion of the exact quotient; if it does,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1719
             * the computed remainder will be less than the divisor.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1720
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1721
            BigDecimal product = result.multiply(divisor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1722
            // If the quotient is the full integer value,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1723
            // |dividend-product| < |divisor|.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1724
            if (this.subtract(product).abs().compareTo(divisor.abs()) >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1725
                throw new ArithmeticException("Division impossible");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1726
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1727
        } else if (result.scale() > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1728
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1729
             * Integer portion of quotient will fit into precision
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1730
             * digits; recompute quotient to scale 0 to avoid double
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1731
             * rounding and then try to adjust, if necessary.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1732
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1733
            result = result.setScale(0, RoundingMode.DOWN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1734
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1735
        // else result.scale() == 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1736
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1737
        int precisionDiff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1738
        if ((preferredScale > result.scale()) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1739
            (precisionDiff = mc.precision - result.precision()) > 0  ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1740
            return result.setScale(result.scale() +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1741
                                   Math.min(precisionDiff, preferredScale - result.scale) );
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1742
        } else
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1743
            return result.stripZerosToMatchScale(preferredScale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1744
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1745
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1746
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1747
     * Returns a {@code BigDecimal} whose value is {@code (this % divisor)}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1748
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1749
     * <p>The remainder is given by
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1750
     * {@code this.subtract(this.divideToIntegralValue(divisor).multiply(divisor))}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1751
     * Note that this is not the modulo operation (the result can be
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1752
     * negative).
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1753
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1754
     * @param  divisor value by which this {@code BigDecimal} is to be divided.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1755
     * @return {@code this % divisor}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1756
     * @throws ArithmeticException if {@code divisor==0}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1757
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1758
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1759
    public BigDecimal remainder(BigDecimal divisor) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1760
        BigDecimal divrem[] = this.divideAndRemainder(divisor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1761
        return divrem[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1762
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1763
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1764
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1765
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1766
     * Returns a {@code BigDecimal} whose value is {@code (this %
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1767
     * divisor)}, with rounding according to the context settings.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1768
     * The {@code MathContext} settings affect the implicit divide
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1769
     * used to compute the remainder.  The remainder computation
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1770
     * itself is by definition exact.  Therefore, the remainder may
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1771
     * contain more than {@code mc.getPrecision()} digits.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1772
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1773
     * <p>The remainder is given by
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1774
     * {@code this.subtract(this.divideToIntegralValue(divisor,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1775
     * mc).multiply(divisor))}.  Note that this is not the modulo
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1776
     * operation (the result can be negative).
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1777
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1778
     * @param  divisor value by which this {@code BigDecimal} is to be divided.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1779
     * @param  mc the context to use.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1780
     * @return {@code this % divisor}, rounded as necessary.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1781
     * @throws ArithmeticException if {@code divisor==0}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1782
     * @throws ArithmeticException if the result is inexact but the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1783
     *         rounding mode is {@code UNNECESSARY}, or {@code mc.precision}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1784
     *         {@literal >} 0 and the result of {@code this.divideToIntgralValue(divisor)} would
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1785
     *         require a precision of more than {@code mc.precision} digits.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1786
     * @see    #divideToIntegralValue(java.math.BigDecimal, java.math.MathContext)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1787
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1788
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1789
    public BigDecimal remainder(BigDecimal divisor, MathContext mc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1790
        BigDecimal divrem[] = this.divideAndRemainder(divisor, mc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1791
        return divrem[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1792
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1793
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1794
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1795
     * Returns a two-element {@code BigDecimal} array containing the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1796
     * result of {@code divideToIntegralValue} followed by the result of
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1797
     * {@code remainder} on the two operands.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1798
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1799
     * <p>Note that if both the integer quotient and remainder are
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1800
     * needed, this method is faster than using the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1801
     * {@code divideToIntegralValue} and {@code remainder} methods
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1802
     * separately because the division need only be carried out once.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1803
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1804
     * @param  divisor value by which this {@code BigDecimal} is to be divided,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1805
     *         and the remainder computed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1806
     * @return a two element {@code BigDecimal} array: the quotient
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1807
     *         (the result of {@code divideToIntegralValue}) is the initial element
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1808
     *         and the remainder is the final element.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1809
     * @throws ArithmeticException if {@code divisor==0}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1810
     * @see    #divideToIntegralValue(java.math.BigDecimal, java.math.MathContext)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1811
     * @see    #remainder(java.math.BigDecimal, java.math.MathContext)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1812
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1813
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1814
    public BigDecimal[] divideAndRemainder(BigDecimal divisor) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1815
        // we use the identity  x = i * y + r to determine r
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1816
        BigDecimal[] result = new BigDecimal[2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1817
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1818
        result[0] = this.divideToIntegralValue(divisor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1819
        result[1] = this.subtract(result[0].multiply(divisor));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1820
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1821
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1822
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1823
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1824
     * Returns a two-element {@code BigDecimal} array containing the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1825
     * result of {@code divideToIntegralValue} followed by the result of
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1826
     * {@code remainder} on the two operands calculated with rounding
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1827
     * according to the context settings.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1828
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1829
     * <p>Note that if both the integer quotient and remainder are
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1830
     * needed, this method is faster than using the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1831
     * {@code divideToIntegralValue} and {@code remainder} methods
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1832
     * separately because the division need only be carried out once.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1833
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1834
     * @param  divisor value by which this {@code BigDecimal} is to be divided,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1835
     *         and the remainder computed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1836
     * @param  mc the context to use.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1837
     * @return a two element {@code BigDecimal} array: the quotient
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1838
     *         (the result of {@code divideToIntegralValue}) is the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1839
     *         initial element and the remainder is the final element.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1840
     * @throws ArithmeticException if {@code divisor==0}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1841
     * @throws ArithmeticException if the result is inexact but the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1842
     *         rounding mode is {@code UNNECESSARY}, or {@code mc.precision}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1843
     *         {@literal >} 0 and the result of {@code this.divideToIntgralValue(divisor)} would
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1844
     *         require a precision of more than {@code mc.precision} digits.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1845
     * @see    #divideToIntegralValue(java.math.BigDecimal, java.math.MathContext)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1846
     * @see    #remainder(java.math.BigDecimal, java.math.MathContext)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1847
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1848
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1849
    public BigDecimal[] divideAndRemainder(BigDecimal divisor, MathContext mc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1850
        if (mc.precision == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1851
            return divideAndRemainder(divisor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1852
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1853
        BigDecimal[] result = new BigDecimal[2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1854
        BigDecimal lhs = this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1855
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1856
        result[0] = lhs.divideToIntegralValue(divisor, mc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1857
        result[1] = lhs.subtract(result[0].multiply(divisor));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1858
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1859
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1860
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1861
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1862
     * Returns a {@code BigDecimal} whose value is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1863
     * <tt>(this<sup>n</sup>)</tt>, The power is computed exactly, to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1864
     * unlimited precision.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1865
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1866
     * <p>The parameter {@code n} must be in the range 0 through
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1867
     * 999999999, inclusive.  {@code ZERO.pow(0)} returns {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1868
     * #ONE}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1869
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1870
     * Note that future releases may expand the allowable exponent
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1871
     * range of this method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1872
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1873
     * @param  n power to raise this {@code BigDecimal} to.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1874
     * @return <tt>this<sup>n</sup></tt>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1875
     * @throws ArithmeticException if {@code n} is out of range.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1876
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1877
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1878
    public BigDecimal pow(int n) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1879
        if (n < 0 || n > 999999999)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1880
            throw new ArithmeticException("Invalid operation");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1881
        // No need to calculate pow(n) if result will over/underflow.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1882
        // Don't attempt to support "supernormal" numbers.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1883
        int newScale = checkScale((long)scale * n);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1884
        this.inflate();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1885
        return new BigDecimal(intVal.pow(n), newScale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1886
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1887
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1888
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1889
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1890
     * Returns a {@code BigDecimal} whose value is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1891
     * <tt>(this<sup>n</sup>)</tt>.  The current implementation uses
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1892
     * the core algorithm defined in ANSI standard X3.274-1996 with
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1893
     * rounding according to the context settings.  In general, the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1894
     * returned numerical value is within two ulps of the exact
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1895
     * numerical value for the chosen precision.  Note that future
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1896
     * releases may use a different algorithm with a decreased
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1897
     * allowable error bound and increased allowable exponent range.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1898
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1899
     * <p>The X3.274-1996 algorithm is:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1900
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1901
     * <ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1902
     * <li> An {@code ArithmeticException} exception is thrown if
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1903
     *  <ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1904
     *    <li>{@code abs(n) > 999999999}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1905
     *    <li>{@code mc.precision == 0} and {@code n < 0}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1906
     *    <li>{@code mc.precision > 0} and {@code n} has more than
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1907
     *    {@code mc.precision} decimal digits
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1908
     *  </ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1909
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1910
     * <li> if {@code n} is zero, {@link #ONE} is returned even if
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1911
     * {@code this} is zero, otherwise
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1912
     * <ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1913
     *   <li> if {@code n} is positive, the result is calculated via
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1914
     *   the repeated squaring technique into a single accumulator.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1915
     *   The individual multiplications with the accumulator use the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1916
     *   same math context settings as in {@code mc} except for a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1917
     *   precision increased to {@code mc.precision + elength + 1}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1918
     *   where {@code elength} is the number of decimal digits in
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1919
     *   {@code n}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1920
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1921
     *   <li> if {@code n} is negative, the result is calculated as if
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1922
     *   {@code n} were positive; this value is then divided into one
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1923
     *   using the working precision specified above.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1924
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1925
     *   <li> The final value from either the positive or negative case
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1926
     *   is then rounded to the destination precision.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1927
     *   </ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1928
     * </ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1929
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1930
     * @param  n power to raise this {@code BigDecimal} to.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1931
     * @param  mc the context to use.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1932
     * @return <tt>this<sup>n</sup></tt> using the ANSI standard X3.274-1996
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1933
     *         algorithm
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1934
     * @throws ArithmeticException if the result is inexact but the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1935
     *         rounding mode is {@code UNNECESSARY}, or {@code n} is out
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1936
     *         of range.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1937
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1938
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1939
    public BigDecimal pow(int n, MathContext mc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1940
        if (mc.precision == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1941
            return pow(n);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1942
        if (n < -999999999 || n > 999999999)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1943
            throw new ArithmeticException("Invalid operation");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1944
        if (n == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1945
            return ONE;                      // x**0 == 1 in X3.274
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1946
        this.inflate();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1947
        BigDecimal lhs = this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1948
        MathContext workmc = mc;           // working settings
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1949
        int mag = Math.abs(n);               // magnitude of n
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1950
        if (mc.precision > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1951
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1952
            int elength = intLength(mag);    // length of n in digits
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1953
            if (elength > mc.precision)        // X3.274 rule
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1954
                throw new ArithmeticException("Invalid operation");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1955
            workmc = new MathContext(mc.precision + elength + 1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1956
                                      mc.roundingMode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1957
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1958
        // ready to carry out power calculation...
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1959
        BigDecimal acc = ONE;           // accumulator
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1960
        boolean seenbit = false;        // set once we've seen a 1-bit
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1961
        for (int i=1;;i++) {            // for each bit [top bit ignored]
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1962
            mag += mag;                 // shift left 1 bit
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1963
            if (mag < 0) {              // top bit is set
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1964
                seenbit = true;         // OK, we're off
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1965
                acc = acc.multiply(lhs, workmc); // acc=acc*x
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1966
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1967
            if (i == 31)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1968
                break;                  // that was the last bit
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1969
            if (seenbit)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1970
                acc=acc.multiply(acc, workmc);   // acc=acc*acc [square]
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1971
                // else (!seenbit) no point in squaring ONE
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1972
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1973
        // if negative n, calculate the reciprocal using working precision
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1974
        if (n<0)                          // [hence mc.precision>0]
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1975
            acc=ONE.divide(acc, workmc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1976
        // round to final precision and strip zeros
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1977
        return acc.doRound(mc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1978
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1979
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1980
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1981
     * Returns a {@code BigDecimal} whose value is the absolute value
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1982
     * of this {@code BigDecimal}, and whose scale is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1983
     * {@code this.scale()}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1984
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1985
     * @return {@code abs(this)}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1986
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1987
    public BigDecimal abs() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1988
        return (signum() < 0 ? negate() : this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1989
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1990
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1991
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1992
     * Returns a {@code BigDecimal} whose value is the absolute value
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1993
     * of this {@code BigDecimal}, with rounding according to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1994
     * context settings.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1995
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1996
     * @param mc the context to use.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1997
     * @return {@code abs(this)}, rounded as necessary.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1998
     * @throws ArithmeticException if the result is inexact but the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1999
     *         rounding mode is {@code UNNECESSARY}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2000
     * @since 1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2001
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2002
    public BigDecimal abs(MathContext mc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2003
        return (signum() < 0 ? negate(mc) : plus(mc));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2004
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2005
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2006
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2007
     * Returns a {@code BigDecimal} whose value is {@code (-this)},
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2008
     * and whose scale is {@code this.scale()}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2009
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2010
     * @return {@code -this}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2011
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2012
    public BigDecimal negate() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2013
        BigDecimal result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2014
        if (intCompact != INFLATED)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2015
            result = BigDecimal.valueOf(-intCompact, scale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2016
        else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2017
            result = new BigDecimal(intVal.negate(), scale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2018
            result.precision = precision;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2019
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2020
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2021
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2022
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2023
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2024
     * Returns a {@code BigDecimal} whose value is {@code (-this)},
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2025
     * with rounding according to the context settings.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2026
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2027
     * @param mc the context to use.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2028
     * @return {@code -this}, rounded as necessary.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2029
     * @throws ArithmeticException if the result is inexact but the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2030
     *         rounding mode is {@code UNNECESSARY}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2031
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2032
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2033
    public BigDecimal negate(MathContext mc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2034
        return negate().plus(mc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2035
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2036
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2037
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2038
     * Returns a {@code BigDecimal} whose value is {@code (+this)}, and whose
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2039
     * scale is {@code this.scale()}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2040
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2041
     * <p>This method, which simply returns this {@code BigDecimal}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2042
     * is included for symmetry with the unary minus method {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2043
     * #negate()}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2044
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2045
     * @return {@code this}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2046
     * @see #negate()
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2047
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2048
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2049
    public BigDecimal plus() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2050
        return this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2051
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2052
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2053
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2054
     * Returns a {@code BigDecimal} whose value is {@code (+this)},
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2055
     * with rounding according to the context settings.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2056
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2057
     * <p>The effect of this method is identical to that of the {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2058
     * #round(MathContext)} method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2059
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2060
     * @param mc the context to use.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2061
     * @return {@code this}, rounded as necessary.  A zero result will
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2062
     *         have a scale of 0.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2063
     * @throws ArithmeticException if the result is inexact but the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2064
     *         rounding mode is {@code UNNECESSARY}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2065
     * @see    #round(MathContext)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2066
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2067
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2068
    public BigDecimal plus(MathContext mc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2069
        if (mc.precision == 0)                 // no rounding please
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2070
            return this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2071
        return this.doRound(mc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2072
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2073
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2074
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2075
     * Returns the signum function of this {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2076
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2077
     * @return -1, 0, or 1 as the value of this {@code BigDecimal}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2078
     *         is negative, zero, or positive.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2079
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2080
    public int signum() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2081
        return (intCompact != INFLATED)?
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2082
            Long.signum(intCompact):
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2083
            intVal.signum();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2084
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2085
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2086
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2087
     * Returns the <i>scale</i> of this {@code BigDecimal}.  If zero
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2088
     * or positive, the scale is the number of digits to the right of
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2089
     * the decimal point.  If negative, the unscaled value of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2090
     * number is multiplied by ten to the power of the negation of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2091
     * scale.  For example, a scale of {@code -3} means the unscaled
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2092
     * value is multiplied by 1000.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2093
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2094
     * @return the scale of this {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2095
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2096
    public int scale() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2097
        return scale;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2098
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2099
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2100
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2101
     * Returns the <i>precision</i> of this {@code BigDecimal}.  (The
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2102
     * precision is the number of digits in the unscaled value.)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2103
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2104
     * <p>The precision of a zero value is 1.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2105
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2106
     * @return the precision of this {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2107
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2108
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2109
    public int precision() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2110
        int result = precision;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2111
        if (result == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2112
            result = digitLength();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2113
            precision = result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2114
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2115
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2116
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2117
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2118
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2119
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2120
     * Returns a {@code BigInteger} whose value is the <i>unscaled
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2121
     * value</i> of this {@code BigDecimal}.  (Computes <tt>(this *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2122
     * 10<sup>this.scale()</sup>)</tt>.)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2123
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2124
     * @return the unscaled value of this {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2125
     * @since  1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2126
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2127
    public BigInteger unscaledValue() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2128
        return this.inflate().intVal;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2129
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2130
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2131
    // Rounding Modes
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2132
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2133
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2134
     * Rounding mode to round away from zero.  Always increments the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2135
     * digit prior to a nonzero discarded fraction.  Note that this rounding
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2136
     * mode never decreases the magnitude of the calculated value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2137
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2138
    public final static int ROUND_UP =           0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2139
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2140
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2141
     * Rounding mode to round towards zero.  Never increments the digit
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2142
     * prior to a discarded fraction (i.e., truncates).  Note that this
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2143
     * rounding mode never increases the magnitude of the calculated value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2144
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2145
    public final static int ROUND_DOWN =         1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2146
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2147
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2148
     * Rounding mode to round towards positive infinity.  If the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2149
     * {@code BigDecimal} is positive, behaves as for
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2150
     * {@code ROUND_UP}; if negative, behaves as for
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2151
     * {@code ROUND_DOWN}.  Note that this rounding mode never
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2152
     * decreases the calculated value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2153
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2154
    public final static int ROUND_CEILING =      2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2155
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2156
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2157
     * Rounding mode to round towards negative infinity.  If the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2158
     * {@code BigDecimal} is positive, behave as for
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2159
     * {@code ROUND_DOWN}; if negative, behave as for
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2160
     * {@code ROUND_UP}.  Note that this rounding mode never
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2161
     * increases the calculated value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2162
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2163
    public final static int ROUND_FLOOR =        3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2164
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2165
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2166
     * Rounding mode to round towards {@literal "nearest neighbor"}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2167
     * unless both neighbors are equidistant, in which case round up.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2168
     * Behaves as for {@code ROUND_UP} if the discarded fraction is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2169
     * &ge; 0.5; otherwise, behaves as for {@code ROUND_DOWN}.  Note
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2170
     * that this is the rounding mode that most of us were taught in
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2171
     * grade school.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2172
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2173
    public final static int ROUND_HALF_UP =      4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2174
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2175
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2176
     * Rounding mode to round towards {@literal "nearest neighbor"}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2177
     * unless both neighbors are equidistant, in which case round
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2178
     * down.  Behaves as for {@code ROUND_UP} if the discarded
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2179
     * fraction is {@literal >} 0.5; otherwise, behaves as for
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2180
     * {@code ROUND_DOWN}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2181
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2182
    public final static int ROUND_HALF_DOWN =    5;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2183
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2184
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2185
     * Rounding mode to round towards the {@literal "nearest neighbor"}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2186
     * unless both neighbors are equidistant, in which case, round
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2187
     * towards the even neighbor.  Behaves as for
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2188
     * {@code ROUND_HALF_UP} if the digit to the left of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2189
     * discarded fraction is odd; behaves as for
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2190
     * {@code ROUND_HALF_DOWN} if it's even.  Note that this is the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2191
     * rounding mode that minimizes cumulative error when applied
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2192
     * repeatedly over a sequence of calculations.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2193
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2194
    public final static int ROUND_HALF_EVEN =    6;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2195
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2196
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2197
     * Rounding mode to assert that the requested operation has an exact
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2198
     * result, hence no rounding is necessary.  If this rounding mode is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2199
     * specified on an operation that yields an inexact result, an
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2200
     * {@code ArithmeticException} is thrown.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2201
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2202
    public final static int ROUND_UNNECESSARY =  7;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2203
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2204
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2205
    // Scaling/Rounding Operations
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2206
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2207
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2208
     * Returns a {@code BigDecimal} rounded according to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2209
     * {@code MathContext} settings.  If the precision setting is 0 then
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2210
     * no rounding takes place.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2211
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2212
     * <p>The effect of this method is identical to that of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2213
     * {@link #plus(MathContext)} method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2214
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2215
     * @param mc the context to use.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2216
     * @return a {@code BigDecimal} rounded according to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2217
     *         {@code MathContext} settings.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2218
     * @throws ArithmeticException if the rounding mode is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2219
     *         {@code UNNECESSARY} and the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2220
     *         {@code BigDecimal}  operation would require rounding.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2221
     * @see    #plus(MathContext)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2222
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2223
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2224
    public BigDecimal round(MathContext mc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2225
        return plus(mc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2226
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2227
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2228
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2229
     * Returns a {@code BigDecimal} whose scale is the specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2230
     * value, and whose unscaled value is determined by multiplying or
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2231
     * dividing this {@code BigDecimal}'s unscaled value by the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2232
     * appropriate power of ten to maintain its overall value.  If the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2233
     * scale is reduced by the operation, the unscaled value must be
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2234
     * divided (rather than multiplied), and the value may be changed;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2235
     * in this case, the specified rounding mode is applied to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2236
     * division.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2237
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2238
     * <p>Note that since BigDecimal objects are immutable, calls of
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2239
     * this method do <i>not</i> result in the original object being
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2240
     * modified, contrary to the usual convention of having methods
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2241
     * named <tt>set<i>X</i></tt> mutate field <i>{@code X}</i>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2242
     * Instead, {@code setScale} returns an object with the proper
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2243
     * scale; the returned object may or may not be newly allocated.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2244
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2245
     * @param  newScale scale of the {@code BigDecimal} value to be returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2246
     * @param  roundingMode The rounding mode to apply.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2247
     * @return a {@code BigDecimal} whose scale is the specified value,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2248
     *         and whose unscaled value is determined by multiplying or
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2249
     *         dividing this {@code BigDecimal}'s unscaled value by the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2250
     *         appropriate power of ten to maintain its overall value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2251
     * @throws ArithmeticException if {@code roundingMode==UNNECESSARY}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2252
     *         and the specified scaling operation would require
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2253
     *         rounding.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2254
     * @see    RoundingMode
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2255
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2256
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2257
    public BigDecimal setScale(int newScale, RoundingMode roundingMode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2258
        return setScale(newScale, roundingMode.oldMode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2259
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2260
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2261
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2262
     * Returns a {@code BigDecimal} whose scale is the specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2263
     * value, and whose unscaled value is determined by multiplying or
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2264
     * dividing this {@code BigDecimal}'s unscaled value by the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2265
     * appropriate power of ten to maintain its overall value.  If the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2266
     * scale is reduced by the operation, the unscaled value must be
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2267
     * divided (rather than multiplied), and the value may be changed;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2268
     * in this case, the specified rounding mode is applied to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2269
     * division.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2270
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2271
     * <p>Note that since BigDecimal objects are immutable, calls of
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2272
     * this method do <i>not</i> result in the original object being
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2273
     * modified, contrary to the usual convention of having methods
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2274
     * named <tt>set<i>X</i></tt> mutate field <i>{@code X}</i>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2275
     * Instead, {@code setScale} returns an object with the proper
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2276
     * scale; the returned object may or may not be newly allocated.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2277
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2278
     * <p>The new {@link #setScale(int, RoundingMode)} method should
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2279
     * be used in preference to this legacy method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2280
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2281
     * @param  newScale scale of the {@code BigDecimal} value to be returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2282
     * @param  roundingMode The rounding mode to apply.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2283
     * @return a {@code BigDecimal} whose scale is the specified value,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2284
     *         and whose unscaled value is determined by multiplying or
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2285
     *         dividing this {@code BigDecimal}'s unscaled value by the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2286
     *         appropriate power of ten to maintain its overall value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2287
     * @throws ArithmeticException if {@code roundingMode==ROUND_UNNECESSARY}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2288
     *         and the specified scaling operation would require
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2289
     *         rounding.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2290
     * @throws IllegalArgumentException if {@code roundingMode} does not
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2291
     *         represent a valid rounding mode.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2292
     * @see    #ROUND_UP
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2293
     * @see    #ROUND_DOWN
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2294
     * @see    #ROUND_CEILING
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2295
     * @see    #ROUND_FLOOR
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2296
     * @see    #ROUND_HALF_UP
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2297
     * @see    #ROUND_HALF_DOWN
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2298
     * @see    #ROUND_HALF_EVEN
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2299
     * @see    #ROUND_UNNECESSARY
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2300
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2301
    public BigDecimal setScale(int newScale, int roundingMode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2302
        if (roundingMode < ROUND_UP || roundingMode > ROUND_UNNECESSARY)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2303
            throw new IllegalArgumentException("Invalid rounding mode");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2304
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2305
        if (newScale == this.scale)        // easy case
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2306
            return this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2307
        if (this.signum() == 0)            // zero can have any scale
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2308
            return BigDecimal.valueOf(0, newScale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2309
        if (newScale > this.scale) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2310
            // [we can use checkScale to assure multiplier is valid]
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2311
            int raise = checkScale((long)newScale - this.scale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2312
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2313
            if (intCompact != INFLATED) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2314
                long scaledResult = longTenToThe(intCompact, raise);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2315
                if (scaledResult != INFLATED)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2316
                    return BigDecimal.valueOf(scaledResult, newScale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2317
                this.inflate();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2318
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2319
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2320
            BigDecimal result = new BigDecimal(intVal.multiply(tenToThe(raise)),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2321
                                               newScale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2322
            if (this.precision > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2323
                result.precision = this.precision + newScale - this.scale;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2324
            return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2325
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2326
        // scale < this.scale
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2327
        // we cannot perfectly predict the precision after rounding
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2328
        return divide(ONE, newScale, roundingMode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2329
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2330
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2331
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2332
     * Returns a {@code BigDecimal} whose scale is the specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2333
     * value, and whose value is numerically equal to this
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2334
     * {@code BigDecimal}'s.  Throws an {@code ArithmeticException}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2335
     * if this is not possible.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2336
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2337
     * <p>This call is typically used to increase the scale, in which
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2338
     * case it is guaranteed that there exists a {@code BigDecimal}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2339
     * of the specified scale and the correct value.  The call can
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2340
     * also be used to reduce the scale if the caller knows that the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2341
     * {@code BigDecimal} has sufficiently many zeros at the end of
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2342
     * its fractional part (i.e., factors of ten in its integer value)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2343
     * to allow for the rescaling without changing its value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2344
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2345
     * <p>This method returns the same result as the two-argument
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2346
     * versions of {@code setScale}, but saves the caller the trouble
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2347
     * of specifying a rounding mode in cases where it is irrelevant.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2348
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2349
     * <p>Note that since {@code BigDecimal} objects are immutable,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2350
     * calls of this method do <i>not</i> result in the original
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2351
     * object being modified, contrary to the usual convention of
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2352
     * having methods named <tt>set<i>X</i></tt> mutate field
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2353
     * <i>{@code X}</i>.  Instead, {@code setScale} returns an
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2354
     * object with the proper scale; the returned object may or may
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2355
     * not be newly allocated.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2356
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2357
     * @param  newScale scale of the {@code BigDecimal} value to be returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2358
     * @return a {@code BigDecimal} whose scale is the specified value, and
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2359
     *         whose unscaled value is determined by multiplying or dividing
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2360
     *         this {@code BigDecimal}'s unscaled value by the appropriate
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2361
     *         power of ten to maintain its overall value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2362
     * @throws ArithmeticException if the specified scaling operation would
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2363
     *         require rounding.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2364
     * @see    #setScale(int, int)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2365
     * @see    #setScale(int, RoundingMode)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2366
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2367
    public BigDecimal setScale(int newScale) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2368
        return setScale(newScale, ROUND_UNNECESSARY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2369
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2370
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2371
    // Decimal Point Motion Operations
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2372
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2373
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2374
     * Returns a {@code BigDecimal} which is equivalent to this one
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2375
     * with the decimal point moved {@code n} places to the left.  If
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2376
     * {@code n} is non-negative, the call merely adds {@code n} to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2377
     * the scale.  If {@code n} is negative, the call is equivalent
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2378
     * to {@code movePointRight(-n)}.  The {@code BigDecimal}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2379
     * returned by this call has value <tt>(this &times;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2380
     * 10<sup>-n</sup>)</tt> and scale {@code max(this.scale()+n,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2381
     * 0)}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2382
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2383
     * @param  n number of places to move the decimal point to the left.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2384
     * @return a {@code BigDecimal} which is equivalent to this one with the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2385
     *         decimal point moved {@code n} places to the left.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2386
     * @throws ArithmeticException if scale overflows.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2387
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2388
    public BigDecimal movePointLeft(int n) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2389
        // Cannot use movePointRight(-n) in case of n==Integer.MIN_VALUE
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2390
        int newScale = checkScale((long)scale + n);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2391
        BigDecimal num;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2392
        if (intCompact != INFLATED)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2393
            num = BigDecimal.valueOf(intCompact, newScale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2394
        else
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2395
            num = new BigDecimal(intVal, newScale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2396
        return (num.scale<0 ? num.setScale(0) : num);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2397
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2398
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2399
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2400
     * Returns a {@code BigDecimal} which is equivalent to this one
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2401
     * with the decimal point moved {@code n} places to the right.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2402
     * If {@code n} is non-negative, the call merely subtracts
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2403
     * {@code n} from the scale.  If {@code n} is negative, the call
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2404
     * is equivalent to {@code movePointLeft(-n)}.  The
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2405
     * {@code BigDecimal} returned by this call has value <tt>(this
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2406
     * &times; 10<sup>n</sup>)</tt> and scale {@code max(this.scale()-n,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2407
     * 0)}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2408
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2409
     * @param  n number of places to move the decimal point to the right.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2410
     * @return a {@code BigDecimal} which is equivalent to this one
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2411
     *         with the decimal point moved {@code n} places to the right.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2412
     * @throws ArithmeticException if scale overflows.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2413
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2414
    public BigDecimal movePointRight(int n) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2415
        // Cannot use movePointLeft(-n) in case of n==Integer.MIN_VALUE
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2416
        int newScale = checkScale((long)scale - n);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2417
        BigDecimal num;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2418
        if (intCompact != INFLATED)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2419
            num = BigDecimal.valueOf(intCompact, newScale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2420
        else
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2421
            num = new BigDecimal(intVal, newScale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2422
        return (num.scale<0 ? num.setScale(0) : num);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2423
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2424
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2425
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2426
     * Returns a BigDecimal whose numerical value is equal to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2427
     * ({@code this} * 10<sup>n</sup>).  The scale of
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2428
     * the result is {@code (this.scale() - n)}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2429
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2430
     * @throws ArithmeticException if the scale would be
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2431
     *         outside the range of a 32-bit integer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2432
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2433
     * @since 1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2434
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2435
    public BigDecimal scaleByPowerOfTen(int n) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2436
        this.inflate();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2437
        BigDecimal num = new BigDecimal(intVal, checkScale((long)scale - n));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2438
        num.precision = precision;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2439
        return num;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2440
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2441
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2442
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2443
     * Returns a {@code BigDecimal} which is numerically equal to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2444
     * this one but with any trailing zeros removed from the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2445
     * representation.  For example, stripping the trailing zeros from
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2446
     * the {@code BigDecimal} value {@code 600.0}, which has
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2447
     * [{@code BigInteger}, {@code scale}] components equals to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2448
     * [6000, 1], yields {@code 6E2} with [{@code BigInteger},
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2449
     * {@code scale}] components equals to [6, -2]
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2450
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2451
     * @return a numerically equal {@code BigDecimal} with any
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2452
     * trailing zeros removed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2453
     * @since 1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2454
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2455
    public BigDecimal stripTrailingZeros() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2456
        this.inflate();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2457
        return (new BigDecimal(intVal, scale)).stripZerosToMatchScale(Long.MIN_VALUE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2458
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2459
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2460
    // Comparison Operations
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2461
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2462
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2463
     * Compares this {@code BigDecimal} with the specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2464
     * {@code BigDecimal}.  Two {@code BigDecimal} objects that are
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2465
     * equal in value but have a different scale (like 2.0 and 2.00)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2466
     * are considered equal by this method.  This method is provided
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2467
     * in preference to individual methods for each of the six boolean
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2468
     * comparison operators ({@literal <}, ==,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2469
     * {@literal >}, {@literal >=}, !=, {@literal <=}).  The
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2470
     * suggested idiom for performing these comparisons is:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2471
     * {@code (x.compareTo(y)} &lt;<i>op</i>&gt; {@code 0)}, where
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2472
     * &lt;<i>op</i>&gt; is one of the six comparison operators.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2473
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2474
     * @param  val {@code BigDecimal} to which this {@code BigDecimal} is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2475
     *         to be compared.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2476
     * @return -1, 0, or 1 as this {@code BigDecimal} is numerically
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2477
     *          less than, equal to, or greater than {@code val}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2478
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2479
    public int compareTo(BigDecimal val) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2480
        if (this.scale == val.scale &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2481
            this.intCompact != INFLATED &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2482
            val.intCompact  != INFLATED)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2483
            return longCompareTo(this.intCompact, val.intCompact);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2484
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2485
        // Optimization: would run fine without the next three lines
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2486
        int sigDiff = signum() - val.signum();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2487
        if (sigDiff != 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2488
            return (sigDiff > 0 ? 1 : -1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2489
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2490
        // If the (adjusted) exponents are different we do not need to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2491
        // expensively match scales and compare the significands
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2492
        int aethis = this.precision() - this.scale;    // [-1]
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2493
        int aeval  =  val.precision() - val.scale;     // [-1]
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2494
        if (aethis < aeval)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2495
            return -this.signum();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2496
        else if (aethis > aeval)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2497
            return this.signum();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2498
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2499
        // Scale and compare intVals
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2500
        BigDecimal arg[] = {this, val};
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2501
        matchScale(arg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2502
        if (arg[0].intCompact != INFLATED &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2503
            arg[1].intCompact != INFLATED)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2504
            return longCompareTo(arg[0].intCompact, arg[1].intCompact);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2505
        return arg[0].inflate().intVal.compareTo(arg[1].inflate().intVal);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2506
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2507
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2508
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2509
     * Compares this {@code BigDecimal} with the specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2510
     * {@code Object} for equality.  Unlike {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2511
     * #compareTo(BigDecimal) compareTo}, this method considers two
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2512
     * {@code BigDecimal} objects equal only if they are equal in
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2513
     * value and scale (thus 2.0 is not equal to 2.00 when compared by
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2514
     * this method).
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2515
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2516
     * @param  x {@code Object} to which this {@code BigDecimal} is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2517
     *         to be compared.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2518
     * @return {@code true} if and only if the specified {@code Object} is a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2519
     *         {@code BigDecimal} whose value and scale are equal to this
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2520
     *         {@code BigDecimal}'s.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2521
     * @see    #compareTo(java.math.BigDecimal)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2522
     * @see    #hashCode
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2523
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2524
    public boolean equals(Object x) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2525
        if (!(x instanceof BigDecimal))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2526
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2527
        BigDecimal xDec = (BigDecimal) x;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2528
        if (scale != xDec.scale)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2529
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2530
        if (this.intCompact != INFLATED && xDec.intCompact != INFLATED)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2531
            return this.intCompact == xDec.intCompact;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2532
        return this.inflate().intVal.equals(xDec.inflate().intVal);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2533
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2534
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2535
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2536
     * Returns the minimum of this {@code BigDecimal} and
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2537
     * {@code val}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2538
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2539
     * @param  val value with which the minimum is to be computed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2540
     * @return the {@code BigDecimal} whose value is the lesser of this
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2541
     *         {@code BigDecimal} and {@code val}.  If they are equal,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2542
     *         as defined by the {@link #compareTo(BigDecimal) compareTo}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2543
     *         method, {@code this} is returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2544
     * @see    #compareTo(java.math.BigDecimal)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2545
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2546
    public BigDecimal min(BigDecimal val) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2547
        return (compareTo(val) <= 0 ? this : val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2548
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2549
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2550
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2551
     * Returns the maximum of this {@code BigDecimal} and {@code val}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2552
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2553
     * @param  val value with which the maximum is to be computed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2554
     * @return the {@code BigDecimal} whose value is the greater of this
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2555
     *         {@code BigDecimal} and {@code val}.  If they are equal,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2556
     *         as defined by the {@link #compareTo(BigDecimal) compareTo}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2557
     *         method, {@code this} is returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2558
     * @see    #compareTo(java.math.BigDecimal)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2559
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2560
    public BigDecimal max(BigDecimal val) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2561
        return (compareTo(val) >= 0 ? this : val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2562
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2563
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2564
    // Hash Function
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2565
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2566
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2567
     * Returns the hash code for this {@code BigDecimal}.  Note that
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2568
     * two {@code BigDecimal} objects that are numerically equal but
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2569
     * differ in scale (like 2.0 and 2.00) will generally <i>not</i>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2570
     * have the same hash code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2571
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2572
     * @return hash code for this {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2573
     * @see #equals(Object)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2574
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2575
    public int hashCode() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2576
        if (intCompact != INFLATED) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2577
            long val2 = (intCompact < 0)?-intCompact:intCompact;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2578
            int temp = (int)( ((int)(val2 >>> 32)) * 31  +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2579
                              (val2 & 0xffffffffL));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2580
            return 31*((intCompact < 0) ?-temp:temp) + scale;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2581
        } else
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2582
            return 31*intVal.hashCode() + scale;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2583
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2584
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2585
    // Format Converters
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2586
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2587
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2588
     * Returns the string representation of this {@code BigDecimal},
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2589
     * using scientific notation if an exponent is needed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2590
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2591
     * <p>A standard canonical string form of the {@code BigDecimal}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2592
     * is created as though by the following steps: first, the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2593
     * absolute value of the unscaled value of the {@code BigDecimal}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2594
     * is converted to a string in base ten using the characters
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2595
     * {@code '0'} through {@code '9'} with no leading zeros (except
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2596
     * if its value is zero, in which case a single {@code '0'}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2597
     * character is used).
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2598
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2599
     * <p>Next, an <i>adjusted exponent</i> is calculated; this is the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2600
     * negated scale, plus the number of characters in the converted
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2601
     * unscaled value, less one.  That is,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2602
     * {@code -scale+(ulength-1)}, where {@code ulength} is the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2603
     * length of the absolute value of the unscaled value in decimal
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2604
     * digits (its <i>precision</i>).
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2605
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2606
     * <p>If the scale is greater than or equal to zero and the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2607
     * adjusted exponent is greater than or equal to {@code -6}, the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2608
     * number will be converted to a character form without using
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2609
     * exponential notation.  In this case, if the scale is zero then
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2610
     * no decimal point is added and if the scale is positive a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2611
     * decimal point will be inserted with the scale specifying the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2612
     * number of characters to the right of the decimal point.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2613
     * {@code '0'} characters are added to the left of the converted
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2614
     * unscaled value as necessary.  If no character precedes the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2615
     * decimal point after this insertion then a conventional
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2616
     * {@code '0'} character is prefixed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2617
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2618
     * <p>Otherwise (that is, if the scale is negative, or the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2619
     * adjusted exponent is less than {@code -6}), the number will be
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2620
     * converted to a character form using exponential notation.  In
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2621
     * this case, if the converted {@code BigInteger} has more than
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2622
     * one digit a decimal point is inserted after the first digit.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2623
     * An exponent in character form is then suffixed to the converted
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2624
     * unscaled value (perhaps with inserted decimal point); this
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2625
     * comprises the letter {@code 'E'} followed immediately by the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2626
     * adjusted exponent converted to a character form.  The latter is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2627
     * in base ten, using the characters {@code '0'} through
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2628
     * {@code '9'} with no leading zeros, and is always prefixed by a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2629
     * sign character {@code '-'} (<tt>'&#92;u002D'</tt>) if the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2630
     * adjusted exponent is negative, {@code '+'}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2631
     * (<tt>'&#92;u002B'</tt>) otherwise).
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2632
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2633
     * <p>Finally, the entire string is prefixed by a minus sign
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2634
     * character {@code '-'} (<tt>'&#92;u002D'</tt>) if the unscaled
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2635
     * value is less than zero.  No sign character is prefixed if the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2636
     * unscaled value is zero or positive.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2637
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2638
     * <p><b>Examples:</b>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2639
     * <p>For each representation [<i>unscaled value</i>, <i>scale</i>]
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2640
     * on the left, the resulting string is shown on the right.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2641
     * <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2642
     * [123,0]      "123"
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2643
     * [-123,0]     "-123"
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2644
     * [123,-1]     "1.23E+3"
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2645
     * [123,-3]     "1.23E+5"
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2646
     * [123,1]      "12.3"
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2647
     * [123,5]      "0.00123"
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2648
     * [123,10]     "1.23E-8"
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2649
     * [-123,12]    "-1.23E-10"
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2650
     * </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2651
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2652
     * <b>Notes:</b>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2653
     * <ol>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2654
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2655
     * <li>There is a one-to-one mapping between the distinguishable
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2656
     * {@code BigDecimal} values and the result of this conversion.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2657
     * That is, every distinguishable {@code BigDecimal} value
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2658
     * (unscaled value and scale) has a unique string representation
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2659
     * as a result of using {@code toString}.  If that string
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2660
     * representation is converted back to a {@code BigDecimal} using
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2661
     * the {@link #BigDecimal(String)} constructor, then the original
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2662
     * value will be recovered.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2663
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2664
     * <li>The string produced for a given number is always the same;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2665
     * it is not affected by locale.  This means that it can be used
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2666
     * as a canonical string representation for exchanging decimal
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2667
     * data, or as a key for a Hashtable, etc.  Locale-sensitive
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2668
     * number formatting and parsing is handled by the {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2669
     * java.text.NumberFormat} class and its subclasses.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2670
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2671
     * <li>The {@link #toEngineeringString} method may be used for
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2672
     * presenting numbers with exponents in engineering notation, and the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2673
     * {@link #setScale(int,RoundingMode) setScale} method may be used for
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2674
     * rounding a {@code BigDecimal} so it has a known number of digits after
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2675
     * the decimal point.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2676
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2677
     * <li>The digit-to-character mapping provided by
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2678
     * {@code Character.forDigit} is used.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2679
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2680
     * </ol>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2681
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2682
     * @return string representation of this {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2683
     * @see    Character#forDigit
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2684
     * @see    #BigDecimal(java.lang.String)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2685
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2686
    public String toString() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2687
        if (stringCache == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2688
            stringCache = layoutChars(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2689
        return stringCache;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2690
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2691
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2692
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2693
     * Returns a string representation of this {@code BigDecimal},
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2694
     * using engineering notation if an exponent is needed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2695
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2696
     * <p>Returns a string that represents the {@code BigDecimal} as
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2697
     * described in the {@link #toString()} method, except that if
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2698
     * exponential notation is used, the power of ten is adjusted to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2699
     * be a multiple of three (engineering notation) such that the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2700
     * integer part of nonzero values will be in the range 1 through
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2701
     * 999.  If exponential notation is used for zero values, a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2702
     * decimal point and one or two fractional zero digits are used so
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2703
     * that the scale of the zero value is preserved.  Note that
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2704
     * unlike the output of {@link #toString()}, the output of this
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2705
     * method is <em>not</em> guaranteed to recover the same [integer,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2706
     * scale] pair of this {@code BigDecimal} if the output string is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2707
     * converting back to a {@code BigDecimal} using the {@linkplain
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2708
     * #BigDecimal(String) string constructor}.  The result of this method meets
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2709
     * the weaker constraint of always producing a numerically equal
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2710
     * result from applying the string constructor to the method's output.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2711
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2712
     * @return string representation of this {@code BigDecimal}, using
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2713
     *         engineering notation if an exponent is needed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2714
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2715
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2716
    public String toEngineeringString() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2717
        return layoutChars(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2718
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2719
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2720
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2721
     * Returns a string representation of this {@code BigDecimal}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2722
     * without an exponent field.  For values with a positive scale,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2723
     * the number of digits to the right of the decimal point is used
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2724
     * to indicate scale.  For values with a zero or negative scale,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2725
     * the resulting string is generated as if the value were
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2726
     * converted to a numerically equal value with zero scale and as
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2727
     * if all the trailing zeros of the zero scale value were present
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2728
     * in the result.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2729
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2730
     * The entire string is prefixed by a minus sign character '-'
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2731
     * (<tt>'&#92;u002D'</tt>) if the unscaled value is less than
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2732
     * zero. No sign character is prefixed if the unscaled value is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2733
     * zero or positive.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2734
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2735
     * Note that if the result of this method is passed to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2736
     * {@linkplain #BigDecimal(String) string constructor}, only the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2737
     * numerical value of this {@code BigDecimal} will necessarily be
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2738
     * recovered; the representation of the new {@code BigDecimal}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2739
     * may have a different scale.  In particular, if this
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2740
     * {@code BigDecimal} has a negative scale, the string resulting
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2741
     * from this method will have a scale of zero when processed by
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2742
     * the string constructor.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2743
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2744
     * (This method behaves analogously to the {@code toString}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2745
     * method in 1.4 and earlier releases.)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2746
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2747
     * @return a string representation of this {@code BigDecimal}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2748
     * without an exponent field.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2749
     * @since 1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2750
     * @see #toString()
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2751
     * @see #toEngineeringString()
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2752
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2753
    public String toPlainString() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2754
        BigDecimal bd = this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2755
        if (bd.scale < 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2756
            bd = bd.setScale(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2757
        bd.inflate();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2758
        if (bd.scale == 0)      // No decimal point
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2759
            return bd.intVal.toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2760
        return bd.getValueString(bd.signum(), bd.intVal.abs().toString(), bd.scale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2761
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2762
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2763
    /* Returns a digit.digit string */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2764
    private String getValueString(int signum, String intString, int scale) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2765
        /* Insert decimal point */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2766
        StringBuilder buf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2767
        int insertionPoint = intString.length() - scale;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2768
        if (insertionPoint == 0) {  /* Point goes right before intVal */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2769
            return (signum<0 ? "-0." : "0.") + intString;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2770
        } else if (insertionPoint > 0) { /* Point goes inside intVal */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2771
            buf = new StringBuilder(intString);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2772
            buf.insert(insertionPoint, '.');
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2773
            if (signum < 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2774
                buf.insert(0, '-');
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2775
        } else { /* We must insert zeros between point and intVal */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2776
            buf = new StringBuilder(3-insertionPoint + intString.length());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2777
            buf.append(signum<0 ? "-0." : "0.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2778
            for (int i=0; i<-insertionPoint; i++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2779
                buf.append('0');
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2780
            buf.append(intString);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2781
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2782
        return buf.toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2783
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2784
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2785
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2786
     * Converts this {@code BigDecimal} to a {@code BigInteger}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2787
     * This conversion is analogous to a <a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2788
     * href="http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#25363"><i>narrowing
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2789
     * primitive conversion</i></a> from {@code double} to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2790
     * {@code long} as defined in the <a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2791
     * href="http://java.sun.com/docs/books/jls/html/">Java Language
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2792
     * Specification</a>: any fractional part of this
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2793
     * {@code BigDecimal} will be discarded.  Note that this
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2794
     * conversion can lose information about the precision of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2795
     * {@code BigDecimal} value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2796
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2797
     * To have an exception thrown if the conversion is inexact (in
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2798
     * other words if a nonzero fractional part is discarded), use the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2799
     * {@link #toBigIntegerExact()} method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2800
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2801
     * @return this {@code BigDecimal} converted to a {@code BigInteger}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2802
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2803
    public BigInteger toBigInteger() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2804
        // force to an integer, quietly
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2805
        return this.setScale(0, ROUND_DOWN).inflate().intVal;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2806
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2807
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2808
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2809
     * Converts this {@code BigDecimal} to a {@code BigInteger},
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2810
     * checking for lost information.  An exception is thrown if this
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2811
     * {@code BigDecimal} has a nonzero fractional part.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2812
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2813
     * @return this {@code BigDecimal} converted to a {@code BigInteger}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2814
     * @throws ArithmeticException if {@code this} has a nonzero
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2815
     *         fractional part.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2816
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2817
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2818
    public BigInteger toBigIntegerExact() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2819
        // round to an integer, with Exception if decimal part non-0
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2820
        return this.setScale(0, ROUND_UNNECESSARY).inflate().intVal;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2821
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2822
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2823
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2824
     * Converts this {@code BigDecimal} to a {@code long}.  This
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2825
     * conversion is analogous to a <a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2826
     * href="http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#25363"><i>narrowing
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2827
     * primitive conversion</i></a> from {@code double} to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2828
     * {@code short} as defined in the <a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2829
     * href="http://java.sun.com/docs/books/jls/html/">Java Language
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2830
     * Specification</a>: any fractional part of this
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2831
     * {@code BigDecimal} will be discarded, and if the resulting
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2832
     * "{@code BigInteger}" is too big to fit in a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2833
     * {@code long}, only the low-order 64 bits are returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2834
     * Note that this conversion can lose information about the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2835
     * overall magnitude and precision of this {@code BigDecimal} value as well
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2836
     * as return a result with the opposite sign.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2837
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2838
     * @return this {@code BigDecimal} converted to a {@code long}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2839
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2840
    public long longValue(){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2841
        return (intCompact != INFLATED && scale == 0) ?
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2842
            intCompact:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2843
            toBigInteger().longValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2844
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2845
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2846
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2847
     * Converts this {@code BigDecimal} to a {@code long}, checking
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2848
     * for lost information.  If this {@code BigDecimal} has a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2849
     * nonzero fractional part or is out of the possible range for a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2850
     * {@code long} result then an {@code ArithmeticException} is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2851
     * thrown.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2852
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2853
     * @return this {@code BigDecimal} converted to a {@code long}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2854
     * @throws ArithmeticException if {@code this} has a nonzero
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2855
     *         fractional part, or will not fit in a {@code long}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2856
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2857
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2858
    public long longValueExact() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2859
        if (intCompact != INFLATED && scale == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2860
            return intCompact;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2861
        // If more than 19 digits in integer part it cannot possibly fit
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2862
        if ((precision() - scale) > 19) // [OK for negative scale too]
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2863
            throw new java.lang.ArithmeticException("Overflow");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2864
        // Fastpath zero and < 1.0 numbers (the latter can be very slow
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2865
        // to round if very small)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2866
        if (this.signum() == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2867
            return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2868
        if ((this.precision() - this.scale) <= 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2869
            throw new ArithmeticException("Rounding necessary");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2870
        // round to an integer, with Exception if decimal part non-0
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2871
        BigDecimal num = this.setScale(0, ROUND_UNNECESSARY).inflate();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2872
        if (num.precision() >= 19) // need to check carefully
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2873
            LongOverflow.check(num);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2874
        return num.intVal.longValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2875
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2876
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2877
    private static class LongOverflow {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2878
        /** BigInteger equal to Long.MIN_VALUE. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2879
        private static final BigInteger LONGMIN = BigInteger.valueOf(Long.MIN_VALUE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2880
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2881
        /** BigInteger equal to Long.MAX_VALUE. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2882
        private static final BigInteger LONGMAX = BigInteger.valueOf(Long.MAX_VALUE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2883
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2884
        public static void check(BigDecimal num) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2885
            if ((num.intVal.compareTo(LONGMIN) < 0) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2886
                (num.intVal.compareTo(LONGMAX) > 0))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2887
                throw new java.lang.ArithmeticException("Overflow");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2888
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2889
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2890
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2891
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2892
     * Converts this {@code BigDecimal} to an {@code int}.  This
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2893
     * conversion is analogous to a <a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2894
     * href="http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#25363"><i>narrowing
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2895
     * primitive conversion</i></a> from {@code double} to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2896
     * {@code short} as defined in the <a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2897
     * href="http://java.sun.com/docs/books/jls/html/">Java Language
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2898
     * Specification</a>: any fractional part of this
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2899
     * {@code BigDecimal} will be discarded, and if the resulting
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2900
     * "{@code BigInteger}" is too big to fit in an
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2901
     * {@code int}, only the low-order 32 bits are returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2902
     * Note that this conversion can lose information about the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2903
     * overall magnitude and precision of this {@code BigDecimal}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2904
     * value as well as return a result with the opposite sign.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2905
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2906
     * @return this {@code BigDecimal} converted to an {@code int}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2907
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2908
    public int intValue() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2909
        return  (intCompact != INFLATED && scale == 0) ?
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2910
            (int)intCompact :
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2911
            toBigInteger().intValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2912
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2913
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2914
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2915
     * Converts this {@code BigDecimal} to an {@code int}, checking
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2916
     * for lost information.  If this {@code BigDecimal} has a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2917
     * nonzero fractional part or is out of the possible range for an
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2918
     * {@code int} result then an {@code ArithmeticException} is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2919
     * thrown.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2920
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2921
     * @return this {@code BigDecimal} converted to an {@code int}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2922
     * @throws ArithmeticException if {@code this} has a nonzero
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2923
     *         fractional part, or will not fit in an {@code int}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2924
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2925
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2926
    public int intValueExact() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2927
       long num;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2928
       num = this.longValueExact();     // will check decimal part
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2929
       if ((int)num != num)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2930
           throw new java.lang.ArithmeticException("Overflow");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2931
       return (int)num;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2932
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2933
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2934
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2935
     * Converts this {@code BigDecimal} to a {@code short}, checking
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2936
     * for lost information.  If this {@code BigDecimal} has a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2937
     * nonzero fractional part or is out of the possible range for a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2938
     * {@code short} result then an {@code ArithmeticException} is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2939
     * thrown.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2940
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2941
     * @return this {@code BigDecimal} converted to a {@code short}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2942
     * @throws ArithmeticException if {@code this} has a nonzero
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2943
     *         fractional part, or will not fit in a {@code short}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2944
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2945
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2946
    public short shortValueExact() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2947
       long num;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2948
       num = this.longValueExact();     // will check decimal part
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2949
       if ((short)num != num)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2950
           throw new java.lang.ArithmeticException("Overflow");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2951
       return (short)num;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2952
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2953
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2954
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2955
     * Converts this {@code BigDecimal} to a {@code byte}, checking
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2956
     * for lost information.  If this {@code BigDecimal} has a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2957
     * nonzero fractional part or is out of the possible range for a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2958
     * {@code byte} result then an {@code ArithmeticException} is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2959
     * thrown.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2960
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2961
     * @return this {@code BigDecimal} converted to a {@code byte}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2962
     * @throws ArithmeticException if {@code this} has a nonzero
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2963
     *         fractional part, or will not fit in a {@code byte}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2964
     * @since  1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2965
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2966
    public byte byteValueExact() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2967
       long num;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2968
       num = this.longValueExact();     // will check decimal part
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2969
       if ((byte)num != num)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2970
           throw new java.lang.ArithmeticException("Overflow");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2971
       return (byte)num;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2972
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2973
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2974
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2975
     * Converts this {@code BigDecimal} to a {@code float}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2976
     * This conversion is similar to the <a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2977
     * href="http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#25363"><i>narrowing
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2978
     * primitive conversion</i></a> from {@code double} to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2979
     * {@code float} defined in the <a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2980
     * href="http://java.sun.com/docs/books/jls/html/">Java Language
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2981
     * Specification</a>: if this {@code BigDecimal} has too great a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2982
     * magnitude to represent as a {@code float}, it will be
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2983
     * converted to {@link Float#NEGATIVE_INFINITY} or {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2984
     * Float#POSITIVE_INFINITY} as appropriate.  Note that even when
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2985
     * the return value is finite, this conversion can lose
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2986
     * information about the precision of the {@code BigDecimal}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2987
     * value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2988
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2989
     * @return this {@code BigDecimal} converted to a {@code float}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2990
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2991
    public float floatValue(){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2992
        if (scale == 0 && intCompact != INFLATED)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2993
                return (float)intCompact;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2994
        // Somewhat inefficient, but guaranteed to work.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2995
        return Float.parseFloat(this.toString());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2996
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2997
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2998
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2999
     * Converts this {@code BigDecimal} to a {@code double}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3000
     * This conversion is similar to the <a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3001
     * href="http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#25363"><i>narrowing
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3002
     * primitive conversion</i></a> from {@code double} to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3003
     * {@code float} as defined in the <a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3004
     * href="http://java.sun.com/docs/books/jls/html/">Java Language
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3005
     * Specification</a>: if this {@code BigDecimal} has too great a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3006
     * magnitude represent as a {@code double}, it will be
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3007
     * converted to {@link Double#NEGATIVE_INFINITY} or {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3008
     * Double#POSITIVE_INFINITY} as appropriate.  Note that even when
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3009
     * the return value is finite, this conversion can lose
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3010
     * information about the precision of the {@code BigDecimal}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3011
     * value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3012
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3013
     * @return this {@code BigDecimal} converted to a {@code double}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3014
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3015
    public double doubleValue(){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3016
        if (scale == 0 && intCompact != INFLATED)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3017
            return (double)intCompact;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3018
        // Somewhat inefficient, but guaranteed to work.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3019
        return Double.parseDouble(this.toString());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3020
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3021
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3022
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3023
     * Returns the size of an ulp, a unit in the last place, of this
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3024
     * {@code BigDecimal}.  An ulp of a nonzero {@code BigDecimal}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3025
     * value is the positive distance between this value and the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3026
     * {@code BigDecimal} value next larger in magnitude with the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3027
     * same number of digits.  An ulp of a zero value is numerically
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3028
     * equal to 1 with the scale of {@code this}.  The result is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3029
     * stored with the same scale as {@code this} so the result
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3030
     * for zero and nonzero values is equal to {@code [1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3031
     * this.scale()]}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3032
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3033
     * @return the size of an ulp of {@code this}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3034
     * @since 1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3035
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3036
    public BigDecimal ulp() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3037
        return BigDecimal.valueOf(1, this.scale());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3038
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3039
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3040
    // Private "Helper" Methods
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3041
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3042
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3043
     * Lay out this {@code BigDecimal} into a {@code char[]} array.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3044
     * The Java 1.2 equivalent to this was called {@code getValueString}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3045
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3046
     * @param  sci {@code true} for Scientific exponential notation;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3047
     *          {@code false} for Engineering
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3048
     * @return string with canonical string representation of this
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3049
     *         {@code BigDecimal}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3050
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3051
    private String layoutChars(boolean sci) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3052
        if (scale == 0)                      // zero scale is trivial
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3053
            return (intCompact != INFLATED) ?
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3054
                Long.toString(intCompact):
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3055
                intVal.toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3056
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3057
        // Get the significand as an absolute value
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3058
        char coeff[];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3059
        if (intCompact != INFLATED)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3060
            coeff = Long.toString(Math.abs(intCompact)).toCharArray();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3061
        else
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3062
            coeff = intVal.abs().toString().toCharArray();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3063
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3064
        // Construct a buffer, with sufficient capacity for all cases.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3065
        // If E-notation is needed, length will be: +1 if negative, +1
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3066
        // if '.' needed, +2 for "E+", + up to 10 for adjusted exponent.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3067
        // Otherwise it could have +1 if negative, plus leading "0.00000"
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3068
        StringBuilder buf=new StringBuilder(coeff.length+14);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3069
        if (signum() < 0)             // prefix '-' if negative
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3070
            buf.append('-');
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3071
        long adjusted = -(long)scale + (coeff.length-1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3072
        if ((scale >= 0) && (adjusted >= -6)) { // plain number
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3073
            int pad = scale - coeff.length;  // count of padding zeros
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3074
            if (pad >= 0) {                  // 0.xxx form
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3075
                buf.append('0');
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3076
                buf.append('.');
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3077
                for (; pad>0; pad--) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3078
                    buf.append('0');
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3079
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3080
                buf.append(coeff);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3081
            } else {                         // xx.xx form
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3082
                buf.append(coeff, 0, -pad);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3083
                buf.append('.');
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3084
                buf.append(coeff, -pad, scale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3085
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3086
        } else { // E-notation is needed
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3087
            if (sci) {                       // Scientific notation
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3088
                buf.append(coeff[0]);        // first character
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3089
                if (coeff.length > 1) {      // more to come
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3090
                    buf.append('.');
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3091
                    buf.append(coeff, 1, coeff.length-1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3092
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3093
            } else {                         // Engineering notation
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3094
                int sig = (int)(adjusted % 3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3095
                if (sig < 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3096
                    sig += 3;                // [adjusted was negative]
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3097
                adjusted -= sig;             // now a multiple of 3
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3098
                sig++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3099
                if (signum() == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3100
                    switch (sig) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3101
                    case 1:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3102
                        buf.append('0'); // exponent is a multiple of three
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3103
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3104
                    case 2:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3105
                        buf.append("0.00");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3106
                        adjusted += 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3107
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3108
                    case 3:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3109
                        buf.append("0.0");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3110
                        adjusted += 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3111
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3112
                    default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3113
                        throw new AssertionError("Unexpected sig value " + sig);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3114
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3115
                } else if (sig >= coeff.length) {   // significand all in integer
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3116
                    buf.append(coeff, 0, coeff.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3117
                    // may need some zeros, too
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3118
                    for (int i = sig - coeff.length; i > 0; i--)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3119
                        buf.append('0');
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3120
                } else {                     // xx.xxE form
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3121
                    buf.append(coeff, 0, sig);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3122
                    buf.append('.');
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3123
                    buf.append(coeff, sig, coeff.length-sig);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3124
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3125
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3126
            if (adjusted != 0) {             // [!sci could have made 0]
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3127
                buf.append('E');
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3128
                if (adjusted > 0)            // force sign for positive
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3129
                    buf.append('+');
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3130
                buf.append(adjusted);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3131
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3132
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3133
        return buf.toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3134
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3135
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3136
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3137
     * Return 10 to the power n, as a {@code BigInteger}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3138
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3139
     * @param  n the power of ten to be returned (>=0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3140
     * @return a {@code BigInteger} with the value (10<sup>n</sup>)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3141
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3142
    private static BigInteger tenToThe(int n) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3143
        if (n < TENPOWERS.length)     // use value from constant array
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3144
            return TENPOWERS[n];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3145
        // BigInteger.pow is slow, so make 10**n by constructing a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3146
        // BigInteger from a character string (still not very fast)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3147
        char tenpow[] = new char[n + 1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3148
        tenpow[0] = '1';
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3149
        for (int i = 1; i <= n; i++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3150
            tenpow[i] = '0';
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3151
        return new BigInteger(tenpow);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3152
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3153
    private static BigInteger TENPOWERS[] = {BigInteger.ONE,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3154
        BigInteger.valueOf(10),       BigInteger.valueOf(100),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3155
        BigInteger.valueOf(1000),     BigInteger.valueOf(10000),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3156
        BigInteger.valueOf(100000),   BigInteger.valueOf(1000000),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3157
        BigInteger.valueOf(10000000), BigInteger.valueOf(100000000),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3158
        BigInteger.valueOf(1000000000)};
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3159
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3160
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3161
     * Compute val * 10 ^ n; return this product if it is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3162
     * representable as a long, INFLATED otherwise.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3163
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3164
    private static long longTenToThe(long val, int n) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3165
        // System.err.print("\tval " + val + "\t power " + n + "\tresult ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3166
        if (n >= 0 && n < thresholds.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3167
            if (Math.abs(val) <= thresholds[n][0] ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3168
                // System.err.println(val * thresholds[n][1]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3169
                return val * thresholds[n][1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3170
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3171
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3172
        // System.err.println(INFLATED);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3173
        return INFLATED;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3174
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3175
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3176
    private static long thresholds[][] = {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3177
        {Long.MAX_VALUE,                        1L},            // 0
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3178
        {Long.MAX_VALUE/10L,                    10L},           // 1
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3179
        {Long.MAX_VALUE/100L,                   100L},          // 2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3180
        {Long.MAX_VALUE/1000L,                  1000L},         // 3
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3181
        {Long.MAX_VALUE/10000L,                 10000L},        // 4
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3182
        {Long.MAX_VALUE/100000L,                100000L},       // 5
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3183
        {Long.MAX_VALUE/1000000L,               1000000L},      // 6
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3184
        {Long.MAX_VALUE/10000000L,              10000000L},     // 7
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3185
        {Long.MAX_VALUE/100000000L,             100000000L},    // 8
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3186
        {Long.MAX_VALUE/1000000000L,            1000000000L},   // 9
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3187
        {Long.MAX_VALUE/10000000000L,           10000000000L},  // 10
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3188
        {Long.MAX_VALUE/100000000000L,          100000000000L}, // 11
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3189
        {Long.MAX_VALUE/1000000000000L,         1000000000000L},// 12
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3190
        {Long.MAX_VALUE/100000000000000L,       10000000000000L},// 13
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3191
    };
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3192
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3193
    private static boolean compactLong(long val) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3194
        return (val != Long.MIN_VALUE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3195
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3196
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3197
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3198
     * Assign appropriate BigInteger to intVal field if intVal is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3199
     * null, i.e. the compact representation is in use.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3200
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3201
    private BigDecimal inflate() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3202
        if (intVal == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3203
            intVal = BigInteger.valueOf(intCompact);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3204
        return this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3205
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3206
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3207
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3208
     * Match the scales of two {@code BigDecimal}s to align their
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3209
     * least significant digits.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3210
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3211
     * <p>If the scales of val[0] and val[1] differ, rescale
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3212
     * (non-destructively) the lower-scaled {@code BigDecimal} so
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3213
     * they match.  That is, the lower-scaled reference will be
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3214
     * replaced by a reference to a new object with the same scale as
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3215
     * the other {@code BigDecimal}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3216
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3217
     * @param  val array of two elements referring to the two
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3218
     *         {@code BigDecimal}s to be aligned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3219
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3220
    private static void matchScale(BigDecimal[] val) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3221
        if (val[0].scale < val[1].scale)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3222
            val[0] = val[0].setScale(val[1].scale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3223
        else if (val[1].scale < val[0].scale)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3224
            val[1] = val[1].setScale(val[0].scale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3225
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3226
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3227
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3228
     * Reconstitute the {@code BigDecimal} instance from a stream (that is,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3229
     * deserialize it).
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3230
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3231
     * @param s the stream being read.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3232
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3233
    private void readObject(java.io.ObjectInputStream s)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3234
        throws java.io.IOException, ClassNotFoundException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3235
        // Read in all fields
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3236
        s.defaultReadObject();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3237
        // validate possibly bad fields
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3238
        if (intVal == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3239
            String message = "BigDecimal: null intVal in stream";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3240
            throw new java.io.StreamCorruptedException(message);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3241
        // [all values of scale are now allowed]
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3242
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3243
        // Set intCompact to uninitialized value; could also see if the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3244
        // intVal was small enough to fit as a compact value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3245
        intCompact = INFLATED;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3246
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3247
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3248
   /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3249
    * Serialize this {@code BigDecimal} to the stream in question
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3250
    *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3251
    * @param s the stream to serialize to.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3252
    */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3253
   private void writeObject(java.io.ObjectOutputStream s)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3254
       throws java.io.IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3255
       // Must inflate to maintain compatible serial form.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3256
       this.inflate();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3257
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3258
       // Write proper fields
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3259
       s.defaultWriteObject();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3260
   }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3261
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3262
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3263
     * Returns the length of this {@code BigDecimal}, in decimal digits.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3264
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3265
     * Notes:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3266
     *<ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3267
     * <li> This is performance-critical; most operations where a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3268
     *      context is supplied will need at least one call to this
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3269
     *      method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3270
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3271
     * <li> This should be a method on BigInteger; the call to this
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3272
     *      method in precision() can then be replaced with the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3273
     *      term: intVal.digitLength().  It could also be called
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3274
     *      precision() in BigInteger.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3275
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3276
     *      Better still -- the precision lookaside could be moved to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3277
     *      BigInteger, too.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3278
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3279
     * <li> This could/should use MutableBigIntegers directly for the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3280
     *      reduction loop.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3281
     *<ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3282
     * @return the length of the unscaled value, in decimal digits
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3283
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3284
    private int digitLength() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3285
        if (intCompact != INFLATED && Math.abs(intCompact) <= Integer.MAX_VALUE)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3286
            return intLength(Math.abs((int)intCompact));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3287
        if (signum() == 0)       // 0 is one decimal digit
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3288
            return 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3289
        this.inflate();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3290
        // we have a nonzero magnitude
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3291
        BigInteger work = intVal;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3292
        int digits = 0;                 // counter
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3293
        for (;work.mag.length>1;) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3294
            // here when more than one integer in the magnitude; divide
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3295
            // by a billion (reduce by 9 digits) and try again
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3296
            work = work.divide(TENPOWERS[9]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3297
            digits += 9;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3298
            if (work.signum() == 0)     // the division was exact
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3299
                return digits;          // (a power of a billion)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3300
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3301
        // down to a simple nonzero integer
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3302
        digits += intLength(work.mag[0]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3303
        // System.out.println("digitLength... "+this+"  ->  "+digits);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3304
        return digits;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3305
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3306
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3307
    private static int[] ilogTable = {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3308
        0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3309
        9,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3310
        99,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3311
        999,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3312
        9999,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3313
        99999,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3314
        999999,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3315
        9999999,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3316
        99999999,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3317
        999999999,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3318
        Integer.MAX_VALUE};
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3319
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3320
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3321
     * Returns the length of an unsigned {@code int}, in decimal digits.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3322
     * @param i the {@code int} (treated as unsigned)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3323
     * @return the length of the unscaled value, in decimal digits
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3324
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3325
    private int intLength(int x) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3326
        int digits;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3327
        if (x < 0) {            // 'negative' is 10 digits unsigned
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3328
            return  10;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3329
        } else {                // positive integer
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3330
            if (x <= 9)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3331
                return 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3332
            // "Hacker's Delight"  section 11-4
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3333
            for(int i = -1; ; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3334
                if (x <= ilogTable[i+1])
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3335
                    return i +1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3336
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3337
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3338
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3339
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3340
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3341
     * Remove insignificant trailing zeros from this
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3342
     * {@code BigDecimal} until the preferred scale is reached or no
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3343
     * more zeros can be removed.  If the preferred scale is less than
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3344
     * Integer.MIN_VALUE, all the trailing zeros will be removed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3345
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3346
     * {@code BigInteger} assistance could help, here?
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3347
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3348
     * <p>WARNING: This method should only be called on new objects as
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3349
     * it mutates the value fields.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3350
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3351
     * @return this {@code BigDecimal} with a scale possibly reduced
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3352
     * to be closed to the preferred scale.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3353
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3354
    private BigDecimal stripZerosToMatchScale(long preferredScale) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3355
        boolean compact = (intCompact != INFLATED);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3356
        this.inflate();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3357
        BigInteger qr[];                // quotient-remainder pair
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3358
        while ( intVal.abs().compareTo(BigInteger.TEN) >= 0 &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3359
                scale > preferredScale) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3360
            if (intVal.testBit(0))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3361
                break;                  // odd number cannot end in 0
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3362
            qr = intVal.divideAndRemainder(BigInteger.TEN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3363
            if (qr[1].signum() != 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3364
                break;                  // non-0 remainder
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3365
            intVal=qr[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3366
            scale = checkScale((long)scale-1);  // could Overflow
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3367
            if (precision > 0)          // adjust precision if known
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3368
              precision--;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3369
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3370
        if (compact)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3371
            intCompact = intVal.longValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3372
        return this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3373
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3374
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3375
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3376
     * Check a scale for Underflow or Overflow.  If this BigDecimal is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3377
     * uninitialized or initialized and nonzero, throw an exception if
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3378
     * the scale is out of range.  If this is zero, saturate the scale
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3379
     * to the extreme value of the right sign if the scale is out of
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3380
     * range.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3381
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3382
     * @param val The new scale.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3383
     * @throws ArithmeticException (overflow or underflow) if the new
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3384
     *         scale is out of range.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3385
     * @return validated scale as an int.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3386
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3387
    private int checkScale(long val) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3388
        if ((int)val != val) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3389
            if ((this.intCompact != INFLATED && this.intCompact != 0) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3390
                (this.intVal   != null     && this.signum() != 0) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3391
                (this.intVal == null && this.intCompact == INFLATED) ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3392
                if (val > Integer.MAX_VALUE)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3393
                    throw new ArithmeticException("Underflow");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3394
                if (val < Integer.MIN_VALUE)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3395
                    throw new ArithmeticException("Overflow");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3396
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3397
                return (val > Integer.MAX_VALUE)?Integer.MAX_VALUE:Integer.MIN_VALUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3398
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3399
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3400
        return (int)val;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3401
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3402
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3403
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3404
     * Round an operand; used only if digits &gt; 0.  Does not change
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3405
     * {@code this}; if rounding is needed a new {@code BigDecimal}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3406
     * is created and returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3407
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3408
     * @param mc the context to use.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3409
     * @throws ArithmeticException if the result is inexact but the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3410
     *         rounding mode is {@code UNNECESSARY}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3411
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3412
    private BigDecimal roundOp(MathContext mc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3413
        BigDecimal rounded = doRound(mc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3414
        return rounded;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3415
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3416
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3417
    /** Round this BigDecimal according to the MathContext settings;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3418
     *  used only if precision {@literal >} 0.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3419
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3420
     * <p>WARNING: This method should only be called on new objects as
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3421
     * it mutates the value fields.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3422
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3423
     * @param mc the context to use.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3424
     * @throws ArithmeticException if the rounding mode is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3425
     *         {@code RoundingMode.UNNECESSARY} and the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3426
     *         {@code BigDecimal} operation would require rounding.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3427
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3428
    private void roundThis(MathContext mc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3429
        BigDecimal rounded = doRound(mc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3430
        if (rounded == this)                 // wasn't rounded
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3431
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3432
        this.intVal     = rounded.intVal;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3433
        this.intCompact = rounded.intCompact;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3434
        this.scale      = rounded.scale;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3435
        this.precision  = rounded.precision;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3436
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3437
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3438
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3439
     * Returns a {@code BigDecimal} rounded according to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3440
     * MathContext settings; used only if {@code mc.precision > 0}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3441
     * Does not change {@code this}; if rounding is needed a new
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3442
     * {@code BigDecimal} is created and returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3443
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3444
     * @param mc the context to use.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3445
     * @return a {@code BigDecimal} rounded according to the MathContext
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3446
     *         settings.  May return this, if no rounding needed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3447
     * @throws ArithmeticException if the rounding mode is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3448
     *         {@code RoundingMode.UNNECESSARY} and the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3449
     *         result is inexact.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3450
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3451
    private BigDecimal doRound(MathContext mc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3452
        this.inflate();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3453
        if (precision == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3454
            if (mc.roundingMax != null
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3455
                && intVal.compareTo(mc.roundingMax) < 0
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3456
                && intVal.compareTo(mc.roundingMin) > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3457
                return this; // no rounding needed
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3458
            precision();                     // find it
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3459
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3460
        int drop = precision - mc.precision;   // digits to discard
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3461
        if (drop <= 0)                       // we fit
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3462
            return this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3463
        BigDecimal rounded = dropDigits(mc, drop);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3464
        // we need to double-check, in case of the 999=>1000 case
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3465
        return rounded.doRound(mc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3466
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3467
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3468
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3469
     * Removes digits from the significand of a {@code BigDecimal},
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3470
     * rounding according to the MathContext settings.  Does not
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3471
     * change {@code this}; a new {@code BigDecimal} is always
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3472
     * created and returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3473
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3474
     * <p>Actual rounding is carried out, as before, by the divide
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3475
     * method, as this minimized code changes.  It might be more
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3476
     * efficient in most cases to move rounding to here, so we can do
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3477
     * a round-to-length rather than round-to-scale.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3478
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3479
     * @param mc the context to use.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3480
     * @param drop the number of digits to drop, must be {@literal >} 0
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3481
     * @return a {@code BigDecimal} rounded according to the MathContext
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3482
     *         settings.  May return {@code this}, if no rounding needed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3483
     * @throws ArithmeticException if the rounding mode is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3484
     *         {@code RoundingMode.UNNECESSARY} and the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3485
     *         result is inexact.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3486
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3487
    private BigDecimal dropDigits(MathContext mc, int drop) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3488
        // here if we need to round; make the divisor = 10**drop)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3489
        // [calculating the BigInteger here saves setScale later]
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3490
        BigDecimal divisor = new BigDecimal(tenToThe(drop), 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3491
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3492
        // divide to same scale to force round to length
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3493
        BigDecimal rounded = this.divide(divisor, scale,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3494
                                         mc.roundingMode.oldMode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3495
        rounded.scale = checkScale((long)rounded.scale - drop ); // adjust the scale
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3496
        return rounded;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3497
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3498
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3499
    private static int longCompareTo(long x, long y) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3500
        return (x < y) ? -1 : (x == y) ? 0 : 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3501
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3502
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3503
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3504
     * Internal printing routine
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3505
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3506
    private static void print(String name, BigDecimal bd) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3507
        System.err.format("%s:\tintCompact %d\tintVal %d\tscale %d\tprecision %d%n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3508
                          name,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3509
                          bd.intCompact,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3510
                          bd.intVal,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3511
                          bd.scale,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3512
                          bd.precision);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3513
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3514
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3515
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3516
     * Check internal invariants of this BigDecimal.  These invariants
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3517
     * include:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3518
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3519
     * <ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3520
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3521
     * <li>The object must be initialized; either intCompact must not be
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3522
     * INFLATED or intVal is non-null.  Both of these conditions may
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3523
     * be true.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3524
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3525
     * <li>If both intCompact and intVal and set, their values must be
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3526
     * consistent.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3527
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3528
     * <li>If precision is nonzero, it must have the right value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3529
     * </ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3530
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3531
    private BigDecimal audit() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3532
        // Check precision
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3533
        if (precision > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3534
            if (precision != digitLength()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3535
                print("audit", this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3536
                throw new AssertionError("precision mismatch");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3537
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3538
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3539
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3540
        if (intCompact == INFLATED) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3541
            if (intVal == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3542
                print("audit", this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3543
                throw new AssertionError("null intVal");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3544
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3545
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3546
            if (intVal != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3547
                long val = intVal.longValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3548
                if (val != intCompact) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3549
                    print("audit", this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3550
                    throw new AssertionError("Inconsistent state, intCompact=" +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3551
                                             intCompact + "\t intVal=" + val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3552
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3553
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3554
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3555
        return this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3556
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  3557
}