1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  this work for additional information regarding copyright ownership.
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  (the "License"); you may not use this file except in compliance with
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  the License.  You may obtain a copy of the License at
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  See the License for the specific language governing permissions and
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  limitations under the License.
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.math;
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException;
21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.ObjectInputStream;
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.ObjectOutputStream;
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.Serializable;
24e866b788d613e0566b85b799fff998a09371520fJesse Wilsonimport java.util.Arrays;
25706de1164836051ab31cc69eb77a6bba1a723896Elliott Hughesimport libcore.math.MathUtils;
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
287cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson * This class represents immutable integer numbers of arbitrary length. Large
297cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson * numbers are typically used in security applications and therefore BigIntegers
307cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson * offer dedicated functionality like the generation of large prime numbers or
317cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson * the computation of modular inverse.
327cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson * <p>
337cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson * Since the class was modeled to offer all the functionality as the {@link Integer}
347cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson * class does, it provides even methods that operate bitwise on a two's
357cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson * complement representation of large integers. Note however that the
367cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson * implementations favors an internal representation where magnitude and sign
377cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson * are treated separately. Hence such operations are inefficient and should be
387cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson * discouraged. In simple words: Do NOT implement any bit fields based on
397cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson * BigInteger.
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class BigDecimal extends Number implements Comparable<BigDecimal>, Serializable {
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Rounding mode where positive values are rounded towards positive infinity
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * and negative values towards negative infinity.
467cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see RoundingMode#UP
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int ROUND_UP = 0;
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Rounding mode where the values are rounded towards zero.
537cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see RoundingMode#DOWN
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int ROUND_DOWN = 1;
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Rounding mode to round towards positive infinity. For positive values
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * this rounding mode behaves as {@link #ROUND_UP}, for negative values as
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@link #ROUND_DOWN}.
627cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see RoundingMode#CEILING
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int ROUND_CEILING = 2;
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Rounding mode to round towards negative infinity. For positive values
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * this rounding mode behaves as {@link #ROUND_DOWN}, for negative values as
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@link #ROUND_UP}.
717cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see RoundingMode#FLOOR
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int ROUND_FLOOR = 3;
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Rounding mode where values are rounded towards the nearest neighbor.
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Ties are broken by rounding up.
797cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see RoundingMode#HALF_UP
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int ROUND_HALF_UP = 4;
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Rounding mode where values are rounded towards the nearest neighbor.
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Ties are broken by rounding down.
877cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see RoundingMode#HALF_DOWN
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int ROUND_HALF_DOWN = 5;
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Rounding mode where values are rounded towards the nearest neighbor.
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Ties are broken by rounding to the even neighbor.
957cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see RoundingMode#HALF_EVEN
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int ROUND_HALF_EVEN = 6;
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Rounding mode where the rounding operations throws an {@code
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * ArithmeticException} for the case that rounding is necessary, i.e. for
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the case that the value cannot be represented exactly.
1047cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see RoundingMode#UNNECESSARY
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int ROUND_UNNECESSARY = 7;
108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /** This is the serialVersionUID used by the sun implementation. */
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final long serialVersionUID = 6108874887143696463L;
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
112e866b788d613e0566b85b799fff998a09371520fJesse Wilson    /** The double closest to {@code Log10(2)}. */
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final double LOG10_2 = 0.3010299956639812;
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /** The <code>String</code> representation is cached. */
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private transient String toStringImage = null;
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /** Cache for the hash code. */
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private transient int hashCode = 0;
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * An array with powers of five that fit in the type <code>long</code>
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * (<code>5^0,5^1,...,5^27</code>).
124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
125e497649548980e13fe7b19a7705de9d246f75535Elliott Hughes    private static final BigInteger[] FIVE_POW;
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * An array with powers of ten that fit in the type <code>long</code>
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * (<code>10^0,10^1,...,10^18</code>).
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
131e497649548980e13fe7b19a7705de9d246f75535Elliott Hughes    private static final BigInteger[] TEN_POW;
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final long[] LONG_FIVE_POW = new long[]
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    {   1L,
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        5L,
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        25L,
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        125L,
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        625L,
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        3125L,
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        15625L,
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        78125L,
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        390625L,
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        1953125L,
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        9765625L,
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        48828125L,
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        244140625L,
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        1220703125L,
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        6103515625L,
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        30517578125L,
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        152587890625L,
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        762939453125L,
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        3814697265625L,
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        19073486328125L,
154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        95367431640625L,
155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        476837158203125L,
156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        2384185791015625L,
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        11920928955078125L,
158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        59604644775390625L,
159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        298023223876953125L,
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        1490116119384765625L,
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        7450580596923828125L, };
1627cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson
163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final int[] LONG_FIVE_POW_BIT_LENGTH = new int[LONG_FIVE_POW.length];
164706de1164836051ab31cc69eb77a6bba1a723896Elliott Hughes    private static final int[] LONG_POWERS_OF_TEN_BIT_LENGTH = new int[MathUtils.LONG_POWERS_OF_TEN.length];
1657cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final int BI_SCALED_BY_ZERO_LENGTH = 11;
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * An array with the first <code>BigInteger</code> scaled by zero.
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * (<code>[0,0],[1,0],...,[10,0]</code>).
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
172e497649548980e13fe7b19a7705de9d246f75535Elliott Hughes    private static final BigDecimal[] BI_SCALED_BY_ZERO = new BigDecimal[BI_SCALED_BY_ZERO_LENGTH];
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * An array with the zero number scaled by the first positive scales.
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * (<code>0*10^0, 0*10^1, ..., 0*10^10</code>).
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
178e497649548980e13fe7b19a7705de9d246f75535Elliott Hughes    private static final BigDecimal[] ZERO_SCALED_BY = new BigDecimal[11];
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /** An array filled with characters <code>'0'</code>. */
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final char[] CH_ZEROS = new char[100];
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    static {
184e497649548980e13fe7b19a7705de9d246f75535Elliott Hughes        Arrays.fill(CH_ZEROS, '0');
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
186e497649548980e13fe7b19a7705de9d246f75535Elliott Hughes        for (int i = 0; i < ZERO_SCALED_BY.length; ++i) {
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            BI_SCALED_BY_ZERO[i] = new BigDecimal(i, 0);
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ZERO_SCALED_BY[i] = new BigDecimal(0, i);
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
190e497649548980e13fe7b19a7705de9d246f75535Elliott Hughes        for (int i = 0; i < LONG_FIVE_POW_BIT_LENGTH.length; ++i) {
191e497649548980e13fe7b19a7705de9d246f75535Elliott Hughes            LONG_FIVE_POW_BIT_LENGTH[i] = bitLength(LONG_FIVE_POW[i]);
192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
193e497649548980e13fe7b19a7705de9d246f75535Elliott Hughes        for (int i = 0; i < LONG_POWERS_OF_TEN_BIT_LENGTH.length; ++i) {
194e497649548980e13fe7b19a7705de9d246f75535Elliott Hughes            LONG_POWERS_OF_TEN_BIT_LENGTH[i] = bitLength(MathUtils.LONG_POWERS_OF_TEN[i]);
195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1967cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Taking the references of useful powers.
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        TEN_POW = Multiplication.bigTenPows;
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        FIVE_POW = Multiplication.bigFivePows;
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
203e497649548980e13fe7b19a7705de9d246f75535Elliott Hughes     * The constant zero as a {@code BigDecimal}.
204e497649548980e13fe7b19a7705de9d246f75535Elliott Hughes     */
205e497649548980e13fe7b19a7705de9d246f75535Elliott Hughes    public static final BigDecimal ZERO = new BigDecimal(0, 0);
206e497649548980e13fe7b19a7705de9d246f75535Elliott Hughes
207e497649548980e13fe7b19a7705de9d246f75535Elliott Hughes    /**
208e497649548980e13fe7b19a7705de9d246f75535Elliott Hughes     * The constant one as a {@code BigDecimal}.
209e497649548980e13fe7b19a7705de9d246f75535Elliott Hughes     */
210e497649548980e13fe7b19a7705de9d246f75535Elliott Hughes    public static final BigDecimal ONE = new BigDecimal(1, 0);
211e497649548980e13fe7b19a7705de9d246f75535Elliott Hughes
212e497649548980e13fe7b19a7705de9d246f75535Elliott Hughes    /**
213e497649548980e13fe7b19a7705de9d246f75535Elliott Hughes     * The constant ten as a {@code BigDecimal}.
214e497649548980e13fe7b19a7705de9d246f75535Elliott Hughes     */
215e497649548980e13fe7b19a7705de9d246f75535Elliott Hughes    public static final BigDecimal TEN = new BigDecimal(10, 0);
216e497649548980e13fe7b19a7705de9d246f75535Elliott Hughes
217e497649548980e13fe7b19a7705de9d246f75535Elliott Hughes    /**
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The arbitrary precision integer (unscaled value) in the internal
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * representation of {@code BigDecimal}.
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private BigInteger intVal;
2227cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson
223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private transient int bitLength;
2247cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson
225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private transient long smallValue;
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2277cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson    /**
2287cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     * The 32-bit integer scale in the internal representation of {@code BigDecimal}.
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private int scale;
231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Represent the number of decimal digits in the unscaled value. This
234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * precision is calculated the first time, and used in the following calls
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * of method <code>precision()</code>. Note that some call to the private
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * method <code>inplaceRound()</code> could update this field.
2377cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #precision()
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #inplaceRound(MathContext)
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private transient int precision = 0;
242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private BigDecimal(long smallValue, int scale){
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.smallValue = smallValue;
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.scale = scale;
246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.bitLength = bitLength(smallValue);
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2487cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson
249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private BigDecimal(int smallValue, int scale){
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.smallValue = smallValue;
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.scale = scale;
252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.bitLength = bitLength(smallValue);
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new {@code BigDecimal} instance from a string representation
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * given as a character array.
2587cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param in
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            array of characters containing the string representation of
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            this {@code BigDecimal}.
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param offset
263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            first index to be copied.
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param len
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            number of characters to be used.
266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NumberFormatException
2678890504f824eca28560987cc23d0b18e8a62bbaaElliott Hughes     *             if {@code offset < 0 || len <= 0 || offset+len-1 < 0 ||
2688890504f824eca28560987cc23d0b18e8a62bbaaElliott Hughes     *             offset+len-1 >= in.length}, or if {@code in} does not
2698890504f824eca28560987cc23d0b18e8a62bbaaElliott Hughes     *             contain a valid string representation of a big decimal.
270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal(char[] in, int offset, int len) {
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int begin = offset; // first index to be copied
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int last = offset + (len - 1); // last index to be copied
274e866b788d613e0566b85b799fff998a09371520fJesse Wilson        String scaleString; // buffer for scale
275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        StringBuilder unscaledBuffer; // buffer for unscaled value
276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long newScale; // the new scale
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (in == null) {
27986acc043d3334651ee26c65467d78d6cefedd397Kenny Root            throw new NullPointerException("in == null");
280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((last >= in.length) || (offset < 0) || (len <= 0) || (last < 0)) {
2821f07ea29bc2d334c55c16227582a7795b8c117c1Elliott Hughes            throw new NumberFormatException("Bad offset/length: offset=" + offset +
2831f07ea29bc2d334c55c16227582a7795b8c117c1Elliott Hughes                    " len=" + len + " in.length=" + in.length);
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        unscaledBuffer = new StringBuilder(len);
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int bufLength = 0;
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // To skip a possible '+' symbol
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((offset <= last) && (in[offset] == '+')) {
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            offset++;
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            begin++;
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int counter = 0;
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        boolean wasNonZero = false;
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Accumulating all digits until a possible decimal point
2951f07ea29bc2d334c55c16227582a7795b8c117c1Elliott Hughes        for (; (offset <= last) && (in[offset] != '.') && (in[offset] != 'e') && (in[offset] != 'E'); offset++) {
296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!wasNonZero) {
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (in[offset] == '0') {
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    counter++;
299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else {
3007cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson                    wasNonZero = true;
3017cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson                }
3027cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson            }
303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        unscaledBuffer.append(in, begin, offset - begin);
306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        bufLength += offset - begin;
307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // A decimal point was found
308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((offset <= last) && (in[offset] == '.')) {
309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            offset++;
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Accumulating all digits until a possible exponent
311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            begin = offset;
312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (; (offset <= last) && (in[offset] != 'e')
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            && (in[offset] != 'E'); offset++) {
314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (!wasNonZero) {
315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (in[offset] == '0') {
316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        counter++;
317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    } else {
3187cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson                        wasNonZero = true;
3197cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson                    }
3207cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson                }
321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            scale = offset - begin;
323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            bufLength +=scale;
324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            unscaledBuffer.append(in, begin, scale);
325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            scale = 0;
327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // An exponent was found
329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((offset <= last) && ((in[offset] == 'e') || (in[offset] == 'E'))) {
330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            offset++;
331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Checking for a possible sign of scale
332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            begin = offset;
333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if ((offset <= last) && (in[offset] == '+')) {
334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                offset++;
335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if ((offset <= last) && (in[offset] != '-')) {
336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    begin++;
337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Accumulating all remaining digits
340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            scaleString = String.valueOf(in, begin, last + 1 - begin);
3417cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson            // Checking if the scale is defined
342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            newScale = (long)scale - Integer.parseInt(scaleString);
343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            scale = (int)newScale;
344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (newScale != scale) {
3458454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes                throw new NumberFormatException("Scale out of range");
346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Parsing the unscaled value
349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (bufLength < 19) {
350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            smallValue = Long.parseLong(unscaledBuffer.toString());
351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            bitLength = bitLength(smallValue);
352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            setUnscaledValue(new BigInteger(unscaledBuffer.toString()));
3547cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson        }
355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        precision = unscaledBuffer.length() - counter;
356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (unscaledBuffer.charAt(0) == '-') {
357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            precision --;
3587cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson        }
359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new {@code BigDecimal} instance from a string representation
363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * given as a character array.
3647cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param in
366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            array of characters containing the string representation of
367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            this {@code BigDecimal}.
368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param offset
369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            first index to be copied.
370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param len
371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            number of characters to be used.
372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param mc
373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            rounding mode and precision for the result of this operation.
374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NumberFormatException
3758890504f824eca28560987cc23d0b18e8a62bbaaElliott Hughes     *             if {@code offset < 0 || len <= 0 || offset+len-1 < 0 ||
3768890504f824eca28560987cc23d0b18e8a62bbaaElliott Hughes     *             offset+len-1 >= in.length}, or if {@code in} does not
3778890504f824eca28560987cc23d0b18e8a62bbaaElliott Hughes     *             contain a valid string representation of a big decimal.
378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code mc.precision > 0} and {@code mc.roundingMode ==
380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             UNNECESSARY} and the new big decimal cannot be represented
381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             within the given precision without rounding.
382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal(char[] in, int offset, int len, MathContext mc) {
384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this(in, offset, len);
385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        inplaceRound(mc);
386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new {@code BigDecimal} instance from a string representation
390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * given as a character array.
3917cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param in
393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            array of characters containing the string representation of
394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            this {@code BigDecimal}.
395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NumberFormatException
396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code in} does not contain a valid string representation
397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             of a big decimal.
398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal(char[] in) {
400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this(in, 0, in.length);
401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new {@code BigDecimal} instance from a string representation
405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * given as a character array. The result is rounded according to the
406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * specified math context.
4077cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param in
409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            array of characters containing the string representation of
410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            this {@code BigDecimal}.
411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param mc
412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            rounding mode and precision for the result of this operation.
413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NumberFormatException
414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code in} does not contain a valid string representation
415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             of a big decimal.
416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code mc.precision > 0} and {@code mc.roundingMode ==
418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             UNNECESSARY} and the new big decimal cannot be represented
419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             within the given precision without rounding.
420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal(char[] in, MathContext mc) {
422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this(in, 0, in.length);
423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        inplaceRound(mc);
424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new {@code BigDecimal} instance from a string
428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * representation.
4297cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param val
431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            string containing the string representation of this {@code
432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            BigDecimal}.
433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NumberFormatException
434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code val} does not contain a valid string representation
435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             of a big decimal.
436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal(String val) {
438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this(val.toCharArray(), 0, val.length());
439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new {@code BigDecimal} instance from a string
443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * representation. The result is rounded according to the specified math
444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * context.
4457cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param val
447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            string containing the string representation of this {@code
448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            BigDecimal}.
449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param mc
450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            rounding mode and precision for the result of this operation.
451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NumberFormatException
452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code val} does not contain a valid string representation
453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             of a big decimal.
454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code mc.precision > 0} and {@code mc.roundingMode ==
456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             UNNECESSARY} and the new big decimal cannot be represented
457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             within the given precision without rounding.
458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal(String val, MathContext mc) {
460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this(val.toCharArray(), 0, val.length());
461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        inplaceRound(mc);
462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new {@code BigDecimal} instance from the 64bit double
466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code val}. The constructed big decimal is equivalent to the given
467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * double. For example, {@code new BigDecimal(0.1)} is equal to {@code
468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * 0.1000000000000000055511151231257827021181583404541015625}. This happens
469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * as {@code 0.1} cannot be represented exactly in binary.
470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * To generate a big decimal instance which is equivalent to {@code 0.1} use
472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the {@code BigDecimal(String)} constructor.
4737cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param val
475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            double value to be converted to a {@code BigDecimal} instance.
476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NumberFormatException
477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code val} is infinity or not a number.
478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal(double val) {
480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (Double.isInfinite(val) || Double.isNaN(val)) {
4811f07ea29bc2d334c55c16227582a7795b8c117c1Elliott Hughes            throw new NumberFormatException("Infinity or NaN: " + val);
482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long bits = Double.doubleToLongBits(val); // IEEE-754
484e866b788d613e0566b85b799fff998a09371520fJesse Wilson        long mantissa;
485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int trailingZeros;
486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Extracting the exponent, note that the bias is 1023
487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        scale = 1075 - (int)((bits >> 52) & 0x7FFL);
488e866b788d613e0566b85b799fff998a09371520fJesse Wilson        // Extracting the 52 bits of the mantissa.
489e866b788d613e0566b85b799fff998a09371520fJesse Wilson        mantissa = (scale == 1075) ? (bits & 0xFFFFFFFFFFFFFL) << 1
490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                : (bits & 0xFFFFFFFFFFFFFL) | 0x10000000000000L;
491e866b788d613e0566b85b799fff998a09371520fJesse Wilson        if (mantissa == 0) {
492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            scale = 0;
493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            precision = 1;
494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
495e866b788d613e0566b85b799fff998a09371520fJesse Wilson        // To simplify all factors '2' in the mantissa
496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (scale > 0) {
497e866b788d613e0566b85b799fff998a09371520fJesse Wilson            trailingZeros = Math.min(scale, Long.numberOfTrailingZeros(mantissa));
498e866b788d613e0566b85b799fff998a09371520fJesse Wilson            mantissa >>>= trailingZeros;
499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            scale -= trailingZeros;
500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Calculating the new unscaled value and the new scale
502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if((bits >> 63) != 0) {
503e866b788d613e0566b85b799fff998a09371520fJesse Wilson            mantissa = -mantissa;
504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
505e866b788d613e0566b85b799fff998a09371520fJesse Wilson        int mantissaBits = bitLength(mantissa);
506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (scale < 0) {
507e866b788d613e0566b85b799fff998a09371520fJesse Wilson            bitLength = mantissaBits == 0 ? 0 : mantissaBits - scale;
508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if(bitLength < 64) {
509e866b788d613e0566b85b799fff998a09371520fJesse Wilson                smallValue = mantissa << (-scale);
510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else {
511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                BigInt bi = new BigInt();
512e866b788d613e0566b85b799fff998a09371520fJesse Wilson                bi.putLongInt(mantissa);
513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                bi.shift(-scale);
514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                intVal = new BigInteger(bi);
515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            scale = 0;
517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else if (scale > 0) {
518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // m * 2^e =  (m * 5^(-e)) * 10^e
519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if(scale < LONG_FIVE_POW.length
520e866b788d613e0566b85b799fff998a09371520fJesse Wilson                    && mantissaBits+LONG_FIVE_POW_BIT_LENGTH[scale] < 64) {
521e866b788d613e0566b85b799fff998a09371520fJesse Wilson                smallValue = mantissa * LONG_FIVE_POW[scale];
522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                bitLength = bitLength(smallValue);
523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else {
524e866b788d613e0566b85b799fff998a09371520fJesse Wilson                setUnscaledValue(Multiplication.multiplyByFivePow(BigInteger.valueOf(mantissa), scale));
525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else { // scale == 0
527e866b788d613e0566b85b799fff998a09371520fJesse Wilson            smallValue = mantissa;
528e866b788d613e0566b85b799fff998a09371520fJesse Wilson            bitLength = mantissaBits;
529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new {@code BigDecimal} instance from the 64bit double
534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code val}. The constructed big decimal is equivalent to the given
535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * double. For example, {@code new BigDecimal(0.1)} is equal to {@code
536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * 0.1000000000000000055511151231257827021181583404541015625}. This happens
537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * as {@code 0.1} cannot be represented exactly in binary.
538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * To generate a big decimal instance which is equivalent to {@code 0.1} use
540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the {@code BigDecimal(String)} constructor.
5417cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param val
543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            double value to be converted to a {@code BigDecimal} instance.
544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param mc
545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            rounding mode and precision for the result of this operation.
546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NumberFormatException
547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code val} is infinity or not a number.
548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code mc.precision > 0} and {@code mc.roundingMode ==
550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             UNNECESSARY} and the new big decimal cannot be represented
551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             within the given precision without rounding.
552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal(double val, MathContext mc) {
554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this(val);
555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        inplaceRound(mc);
556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new {@code BigDecimal} instance from the given big integer
560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code val}. The scale of the result is {@code 0}.
5617cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param val
563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            {@code BigInteger} value to be converted to a {@code
564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            BigDecimal} instance.
565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal(BigInteger val) {
567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this(val, 0);
568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new {@code BigDecimal} instance from the given big integer
572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code val}. The scale of the result is {@code 0}.
5737cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param val
575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            {@code BigInteger} value to be converted to a {@code
576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            BigDecimal} instance.
577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param mc
578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            rounding mode and precision for the result of this operation.
579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code mc.precision > 0} and {@code mc.roundingMode ==
581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             UNNECESSARY} and the new big decimal cannot be represented
582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             within the given precision without rounding.
583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal(BigInteger val, MathContext mc) {
585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this(val);
586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        inplaceRound(mc);
587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new {@code BigDecimal} instance from a given unscaled value
591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code unscaledVal} and a given scale. The value of this instance is
592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code unscaledVal} 10^(-{@code scale}).
5937cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param unscaledVal
595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            {@code BigInteger} representing the unscaled value of this
596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            {@code BigDecimal} instance.
597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param scale
598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            scale of this {@code BigDecimal} instance.
599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code unscaledVal == null}.
601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal(BigInteger unscaledVal, int scale) {
603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (unscaledVal == null) {
60486acc043d3334651ee26c65467d78d6cefedd397Kenny Root            throw new NullPointerException("unscaledVal == null");
605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.scale = scale;
607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        setUnscaledValue(unscaledVal);
608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new {@code BigDecimal} instance from a given unscaled value
612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code unscaledVal} and a given scale. The value of this instance is
613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code unscaledVal} 10^(-{@code scale}). The result is rounded according
614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * to the specified math context.
6157cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param unscaledVal
617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            {@code BigInteger} representing the unscaled value of this
618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            {@code BigDecimal} instance.
619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param scale
620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            scale of this {@code BigDecimal} instance.
621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param mc
622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            rounding mode and precision for the result of this operation.
623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code mc.precision > 0} and {@code mc.roundingMode ==
625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             UNNECESSARY} and the new big decimal cannot be represented
626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             within the given precision without rounding.
627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code unscaledVal == null}.
629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal(BigInteger unscaledVal, int scale, MathContext mc) {
631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this(unscaledVal, scale);
632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        inplaceRound(mc);
633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new {@code BigDecimal} instance from the given int
637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code val}. The scale of the result is 0.
6387cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param val
640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            int value to be converted to a {@code BigDecimal} instance.
641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal(int val) {
643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this(val,0);
644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new {@code BigDecimal} instance from the given int {@code
648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * val}. The scale of the result is {@code 0}. The result is rounded
649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * according to the specified math context.
6507cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param val
652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            int value to be converted to a {@code BigDecimal} instance.
653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param mc
654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            rounding mode and precision for the result of this operation.
655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code mc.precision > 0} and {@code c.roundingMode ==
657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             UNNECESSARY} and the new big decimal cannot be represented
658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             within the given precision without rounding.
659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal(int val, MathContext mc) {
661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this(val,0);
662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        inplaceRound(mc);
663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
665adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new {@code BigDecimal} instance from the given long {@code
667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * val}. The scale of the result is {@code 0}.
6687cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param val
670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            long value to be converted to a {@code BigDecimal} instance.
671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal(long val) {
673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this(val,0);
674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new {@code BigDecimal} instance from the given long {@code
678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * val}. The scale of the result is {@code 0}. The result is rounded
679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * according to the specified math context.
6807cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param val
682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            long value to be converted to a {@code BigDecimal} instance.
683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param mc
684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            rounding mode and precision for the result of this operation.
685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code mc.precision > 0} and {@code mc.roundingMode ==
687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             UNNECESSARY} and the new big decimal cannot be represented
688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             within the given precision without rounding.
689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal(long val, MathContext mc) {
691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this(val);
692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        inplaceRound(mc);
693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /* Public Methods */
696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new {@code BigDecimal} instance whose value is equal to {@code
699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * unscaledVal} 10^(-{@code scale}). The scale of the result is {@code
700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * scale}, and its unscaled value is {@code unscaledVal}.
7017cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param unscaledVal
703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            unscaled value to be used to construct the new {@code
704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            BigDecimal}.
705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param scale
706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            scale to be used to construct the new {@code BigDecimal}.
707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code BigDecimal} instance with the value {@code unscaledVal}*
708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         10^(-{@code unscaledVal}).
709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static BigDecimal valueOf(long unscaledVal, int scale) {
711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (scale == 0) {
712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return valueOf(unscaledVal);
713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((unscaledVal == 0) && (scale >= 0)
715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                && (scale < ZERO_SCALED_BY.length)) {
716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return ZERO_SCALED_BY[scale];
717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return new BigDecimal(unscaledVal, scale);
719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new {@code BigDecimal} instance whose value is equal to {@code
723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * unscaledVal}. The scale of the result is {@code 0}, and its unscaled
724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * value is {@code unscaledVal}.
7257cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param unscaledVal
727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            value to be converted to a {@code BigDecimal}.
728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code BigDecimal} instance with the value {@code unscaledVal}.
729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static BigDecimal valueOf(long unscaledVal) {
731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((unscaledVal >= 0) && (unscaledVal < BI_SCALED_BY_ZERO_LENGTH)) {
732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return BI_SCALED_BY_ZERO[(int)unscaledVal];
733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return new BigDecimal(unscaledVal,0);
735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new {@code BigDecimal} instance whose value is equal to {@code
7397cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     * val}. The new decimal is constructed as if the {@code BigDecimal(String)}
7407cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     * constructor is called with an argument which is equal to {@code
7417cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     * Double.toString(val)}. For example, {@code valueOf("0.1")} is converted to
7427cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     * (unscaled=1, scale=1), although the double {@code 0.1} cannot be
7437cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     * represented exactly as a double value. In contrast to that, a new {@code
7447cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     * BigDecimal(0.1)} instance has the value {@code
745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * 0.1000000000000000055511151231257827021181583404541015625} with an
7467cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     * unscaled value {@code 1000000000000000055511151231257827021181583404541015625}
7477cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     * and the scale {@code 55}.
7487cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param val
750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            double value to be converted to a {@code BigDecimal}.
751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code BigDecimal} instance with the value {@code val}.
752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NumberFormatException
753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code val} is infinite or {@code val} is not a number
754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static BigDecimal valueOf(double val) {
756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (Double.isInfinite(val) || Double.isNaN(val)) {
7571f07ea29bc2d334c55c16227582a7795b8c117c1Elliott Hughes            throw new NumberFormatException("Infinity or NaN: " + val);
758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return new BigDecimal(Double.toString(val));
760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new {@code BigDecimal} whose value is {@code this + augend}.
764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The scale of the result is the maximum of the scales of the two
765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * arguments.
7667cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param augend
768adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            value to be added to {@code this}.
769adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code this + augend}.
770adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
771adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code augend == null}.
772adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal add(BigDecimal augend) {
774adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int diffScale = this.scale - augend.scale;
775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Fast return when some operand is zero
776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.isZero()) {
777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (diffScale <= 0) {
778adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return augend;
779adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
780adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (augend.isZero()) {
781adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return this;
782adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
783adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else if (augend.isZero()) {
784adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (diffScale >= 0) {
785adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return this;
786adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
787adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
788adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Let be:  this = [u1,s1]  and  augend = [u2,s2]
789adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (diffScale == 0) {
790adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // case s1 == s2: [u1 + u2 , s1]
791adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (Math.max(this.bitLength, augend.bitLength) + 1 < 64) {
792adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return valueOf(this.smallValue + augend.smallValue, this.scale);
793adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
794adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return new BigDecimal(this.getUnscaledValue().add(augend.getUnscaledValue()), this.scale);
795adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else if (diffScale > 0) {
796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // case s1 > s2 : [(u1 + u2) * 10 ^ (s1 - s2) , s1]
797adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return addAndMult10(this, augend, diffScale);
798adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {// case s2 > s1 : [(u2 + u1) * 10 ^ (s2 - s1) , s2]
799adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return addAndMult10(augend, this, -diffScale);
800adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
801adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
802adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
803adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static BigDecimal addAndMult10(BigDecimal thisValue,BigDecimal augend, int diffScale) {
804706de1164836051ab31cc69eb77a6bba1a723896Elliott Hughes        if(diffScale < MathUtils.LONG_POWERS_OF_TEN.length &&
805706de1164836051ab31cc69eb77a6bba1a723896Elliott Hughes                Math.max(thisValue.bitLength,augend.bitLength+LONG_POWERS_OF_TEN_BIT_LENGTH[diffScale])+1<64) {
806706de1164836051ab31cc69eb77a6bba1a723896Elliott Hughes            return valueOf(thisValue.smallValue+augend.smallValue*MathUtils.LONG_POWERS_OF_TEN[diffScale],thisValue.scale);
807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
808fd3f1748b8627e8b6ee907bdaad4cbf2abd7403bJesse Wilson            BigInt bi = Multiplication.multiplyByTenPow(augend.getUnscaledValue(),diffScale).getBigInt();
809fd3f1748b8627e8b6ee907bdaad4cbf2abd7403bJesse Wilson            bi.add(thisValue.getUnscaledValue().getBigInt());
810adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return new BigDecimal(new BigInteger(bi), thisValue.scale);
811adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
812adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
8137cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson
814adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
815adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new {@code BigDecimal} whose value is {@code this + augend}.
816adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The result is rounded according to the passed context {@code mc}.
8177cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
818adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param augend
819adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            value to be added to {@code this}.
820adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param mc
821adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            rounding mode and precision for the result of this operation.
822adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code this + augend}.
823adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
824adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code augend == null} or {@code mc == null}.
825adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal add(BigDecimal augend, MathContext mc) {
827adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        BigDecimal larger; // operand with the largest unscaled value
828adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        BigDecimal smaller; // operand with the smallest unscaled value
829adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        BigInteger tempBI;
830adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long diffScale = (long)this.scale - augend.scale;
831adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int largerSignum;
8327cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson        // Some operand is zero or the precision is infinity
833adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((augend.isZero()) || (this.isZero())
834adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                || (mc.getPrecision() == 0)) {
835adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return add(augend).round(mc);
836adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
837adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Cases where there is room for optimizations
838e866b788d613e0566b85b799fff998a09371520fJesse Wilson        if (this.approxPrecision() < diffScale - 1) {
839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            larger = augend;
840adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            smaller = this;
841e866b788d613e0566b85b799fff998a09371520fJesse Wilson        } else if (augend.approxPrecision() < -diffScale - 1) {
842adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            larger = this;
843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            smaller = augend;
8447cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson        } else {// No optimization is done
845adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return add(augend).round(mc);
846adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
847e866b788d613e0566b85b799fff998a09371520fJesse Wilson        if (mc.getPrecision() >= larger.approxPrecision()) {
848adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // No optimization is done
849adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return add(augend).round(mc);
850adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
8517cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson        // Cases where it's unnecessary to add two numbers with very different scales
852adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        largerSignum = larger.signum();
853adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (largerSignum == smaller.signum()) {
854adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            tempBI = Multiplication.multiplyByPositiveInt(larger.getUnscaledValue(),10)
855adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            .add(BigInteger.valueOf(largerSignum));
856adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
857adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            tempBI = larger.getUnscaledValue().subtract(
858adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    BigInteger.valueOf(largerSignum));
859adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            tempBI = Multiplication.multiplyByPositiveInt(tempBI,10)
860adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            .add(BigInteger.valueOf(largerSignum * 9));
861adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
8627cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson        // Rounding the improved adding
863adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        larger = new BigDecimal(tempBI, larger.scale + 1);
864adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return larger.round(mc);
865adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
866adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
867adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
8687cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     * Returns a new {@code BigDecimal} whose value is {@code this - subtrahend}.
8697cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     * The scale of the result is the maximum of the scales of the two arguments.
8707cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
871adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param subtrahend
872adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            value to be subtracted from {@code this}.
873adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code this - subtrahend}.
874adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
875adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code subtrahend == null}.
876adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
877adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal subtract(BigDecimal subtrahend) {
878adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int diffScale = this.scale - subtrahend.scale;
879adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Fast return when some operand is zero
880adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.isZero()) {
881adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (diffScale <= 0) {
882adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return subtrahend.negate();
883adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
884adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (subtrahend.isZero()) {
885adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return this;
886adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
887adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else if (subtrahend.isZero()) {
888adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (diffScale >= 0) {
889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return this;
890adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
891adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
892adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Let be: this = [u1,s1] and subtrahend = [u2,s2] so:
893adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (diffScale == 0) {
894adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // case s1 = s2 : [u1 - u2 , s1]
895adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (Math.max(this.bitLength, subtrahend.bitLength) + 1 < 64) {
896adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return valueOf(this.smallValue - subtrahend.smallValue,this.scale);
897adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
898adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return new BigDecimal(this.getUnscaledValue().subtract(subtrahend.getUnscaledValue()), this.scale);
899adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else if (diffScale > 0) {
900adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // case s1 > s2 : [ u1 - u2 * 10 ^ (s1 - s2) , s1 ]
901706de1164836051ab31cc69eb77a6bba1a723896Elliott Hughes            if(diffScale < MathUtils.LONG_POWERS_OF_TEN.length &&
902706de1164836051ab31cc69eb77a6bba1a723896Elliott Hughes                    Math.max(this.bitLength,subtrahend.bitLength+LONG_POWERS_OF_TEN_BIT_LENGTH[diffScale])+1<64) {
903706de1164836051ab31cc69eb77a6bba1a723896Elliott Hughes                return valueOf(this.smallValue-subtrahend.smallValue*MathUtils.LONG_POWERS_OF_TEN[diffScale],this.scale);
904adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
905adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return new BigDecimal(this.getUnscaledValue().subtract(
906adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    Multiplication.multiplyByTenPow(subtrahend.getUnscaledValue(),diffScale)), this.scale);
907adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {// case s2 > s1 : [ u1 * 10 ^ (s2 - s1) - u2 , s2 ]
908adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            diffScale = -diffScale;
909706de1164836051ab31cc69eb77a6bba1a723896Elliott Hughes            if(diffScale < MathUtils.LONG_POWERS_OF_TEN.length &&
910706de1164836051ab31cc69eb77a6bba1a723896Elliott Hughes                    Math.max(this.bitLength+LONG_POWERS_OF_TEN_BIT_LENGTH[diffScale],subtrahend.bitLength)+1<64) {
911706de1164836051ab31cc69eb77a6bba1a723896Elliott Hughes                return valueOf(this.smallValue*MathUtils.LONG_POWERS_OF_TEN[diffScale]-subtrahend.smallValue,subtrahend.scale);
912adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
913adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return new BigDecimal(Multiplication.multiplyByTenPow(this.getUnscaledValue(),diffScale)
914adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            .subtract(subtrahend.getUnscaledValue()), subtrahend.scale);
915adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
916adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
917adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
918adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
919adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new {@code BigDecimal} whose value is {@code this - subtrahend}.
920adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The result is rounded according to the passed context {@code mc}.
9217cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
922adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param subtrahend
923adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            value to be subtracted from {@code this}.
924adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param mc
925adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            rounding mode and precision for the result of this operation.
926adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code this - subtrahend}.
927adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
928adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code subtrahend == null} or {@code mc == null}.
929adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
930adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal subtract(BigDecimal subtrahend, MathContext mc) {
931adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long diffScale = subtrahend.scale - (long)this.scale;
932adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int thisSignum;
9337cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson        BigDecimal leftOperand; // it will be only the left operand (this)
934adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        BigInteger tempBI;
9357cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson        // Some operand is zero or the precision is infinity
936adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((subtrahend.isZero()) || (this.isZero())
937adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                || (mc.getPrecision() == 0)) {
938adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return subtract(subtrahend).round(mc);
939adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
940adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Now:   this != 0   and   subtrahend != 0
941e866b788d613e0566b85b799fff998a09371520fJesse Wilson        if (subtrahend.approxPrecision() < diffScale - 1) {
942adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Cases where it is unnecessary to subtract two numbers with very different scales
943e866b788d613e0566b85b799fff998a09371520fJesse Wilson            if (mc.getPrecision() < this.approxPrecision()) {
944adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                thisSignum = this.signum();
945adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (thisSignum != subtrahend.signum()) {
946adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    tempBI = Multiplication.multiplyByPositiveInt(this.getUnscaledValue(), 10)
947adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    .add(BigInteger.valueOf(thisSignum));
948adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else {
949adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    tempBI = this.getUnscaledValue().subtract(BigInteger.valueOf(thisSignum));
950adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    tempBI = Multiplication.multiplyByPositiveInt(tempBI, 10)
951adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    .add(BigInteger.valueOf(thisSignum * 9));
952adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
953adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // Rounding the improved subtracting
954adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                leftOperand = new BigDecimal(tempBI, this.scale + 1);
955adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return leftOperand.round(mc);
956adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
957adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
958adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // No optimization is done
959adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return subtract(subtrahend).round(mc);
960adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
961adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
962adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
963adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new {@code BigDecimal} whose value is {@code this *
964adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * multiplicand}. The scale of the result is the sum of the scales of the
965adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * two arguments.
9667cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
967adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param multiplicand
968adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            value to be multiplied with {@code this}.
969adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code this * multiplicand}.
970adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
971adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code multiplicand == null}.
972adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
973adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal multiply(BigDecimal multiplicand) {
974adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long newScale = (long)this.scale + multiplicand.scale;
975adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
976adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((this.isZero()) || (multiplicand.isZero())) {
977adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return zeroScaledBy(newScale);
978adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
979adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /* Let be: this = [u1,s1] and multiplicand = [u2,s2] so:
980adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * this x multiplicand = [ s1 * s2 , s1 + s2 ] */
981adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if(this.bitLength + multiplicand.bitLength < 64) {
9822850a53dfbd0c172aedaec3493aad572a5ec023dJesse Wilson            return valueOf(this.smallValue*multiplicand.smallValue, safeLongToInt(newScale));
983adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
984adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return new BigDecimal(this.getUnscaledValue().multiply(
9852850a53dfbd0c172aedaec3493aad572a5ec023dJesse Wilson                multiplicand.getUnscaledValue()), safeLongToInt(newScale));
986adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
987adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
988adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
989adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new {@code BigDecimal} whose value is {@code this *
990adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * multiplicand}. The result is rounded according to the passed context
991adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code mc}.
9927cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
993adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param multiplicand
994adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            value to be multiplied with {@code this}.
995adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param mc
996adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            rounding mode and precision for the result of this operation.
997adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code this * multiplicand}.
998adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
999adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code multiplicand == null} or {@code mc == null}.
1000adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1001adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal multiply(BigDecimal multiplicand, MathContext mc) {
1002adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        BigDecimal result = multiply(multiplicand);
1003adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1004adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        result.inplaceRound(mc);
1005adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result;
1006adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1007adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1008adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1009adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new {@code BigDecimal} whose value is {@code this / divisor}.
1010adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * As scale of the result the parameter {@code scale} is used. If rounding
1011adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * is required to meet the specified scale, then the specified rounding mode
1012adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code roundingMode} is applied.
10137cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
1014adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param divisor
1015adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            value by which {@code this} is divided.
1016adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param scale
1017adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the scale of the result returned.
1018adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param roundingMode
1019adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            rounding mode to be used to round the result.
1020adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code this / divisor} rounded according to the given rounding
1021adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         mode.
1022adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
1023adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code divisor == null}.
1024adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
1025adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code roundingMode} is not a valid rounding mode.
1026adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
1027adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code divisor == 0}.
1028adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
1029adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code roundingMode == ROUND_UNNECESSARY} and rounding is
1030adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             necessary according to the given scale.
1031adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1032adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode) {
1033adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return divide(divisor, scale, RoundingMode.valueOf(roundingMode));
1034adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1035adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1036adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1037adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new {@code BigDecimal} whose value is {@code this / divisor}.
1038adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * As scale of the result the parameter {@code scale} is used. If rounding
1039adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * is required to meet the specified scale, then the specified rounding mode
1040adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code roundingMode} is applied.
10417cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
1042adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param divisor
1043adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            value by which {@code this} is divided.
1044adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param scale
1045adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the scale of the result returned.
1046adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param roundingMode
1047adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            rounding mode to be used to round the result.
1048adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code this / divisor} rounded according to the given rounding
1049adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         mode.
1050adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
1051adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code divisor == null} or {@code roundingMode == null}.
1052adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
1053adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code divisor == 0}.
1054adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
1055adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code roundingMode == RoundingMode.UNNECESSAR}Y and
1056adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             rounding is necessary according to the given scale and given
1057adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             precision.
1058adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1059adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal divide(BigDecimal divisor, int scale, RoundingMode roundingMode) {
1060adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Let be: this = [u1,s1]  and  divisor = [u2,s2]
1061adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (roundingMode == null) {
106286acc043d3334651ee26c65467d78d6cefedd397Kenny Root            throw new NullPointerException("roundingMode == null");
1063adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1064adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (divisor.isZero()) {
10658454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes            throw new ArithmeticException("Division by zero");
1066adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
10677cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson
1068adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long diffScale = ((long)this.scale - divisor.scale) - scale;
1069adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if(this.bitLength < 64 && divisor.bitLength < 64 ) {
1070adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if(diffScale == 0) {
1071adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return dividePrimitiveLongs(this.smallValue,
1072adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        divisor.smallValue,
1073adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        scale,
1074adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        roundingMode );
1075adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else if(diffScale > 0) {
1076706de1164836051ab31cc69eb77a6bba1a723896Elliott Hughes                if(diffScale < MathUtils.LONG_POWERS_OF_TEN.length &&
1077706de1164836051ab31cc69eb77a6bba1a723896Elliott Hughes                        divisor.bitLength + LONG_POWERS_OF_TEN_BIT_LENGTH[(int)diffScale] < 64) {
1078adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return dividePrimitiveLongs(this.smallValue,
1079706de1164836051ab31cc69eb77a6bba1a723896Elliott Hughes                            divisor.smallValue*MathUtils.LONG_POWERS_OF_TEN[(int)diffScale],
1080adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            scale,
1081adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            roundingMode);
1082adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1083adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else { // diffScale < 0
1084706de1164836051ab31cc69eb77a6bba1a723896Elliott Hughes                if(-diffScale < MathUtils.LONG_POWERS_OF_TEN.length &&
1085706de1164836051ab31cc69eb77a6bba1a723896Elliott Hughes                        this.bitLength + LONG_POWERS_OF_TEN_BIT_LENGTH[(int)-diffScale] < 64) {
1086706de1164836051ab31cc69eb77a6bba1a723896Elliott Hughes                    return dividePrimitiveLongs(this.smallValue*MathUtils.LONG_POWERS_OF_TEN[(int)-diffScale],
1087adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            divisor.smallValue,
1088adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            scale,
1089adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            roundingMode);
1090adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
10917cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson
1092adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1093adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1094adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        BigInteger scaledDividend = this.getUnscaledValue();
1095adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        BigInteger scaledDivisor = divisor.getUnscaledValue(); // for scaling of 'u2'
10967cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson
1097adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (diffScale > 0) {
1098adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Multiply 'u2'  by:  10^((s1 - s2) - scale)
1099adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            scaledDivisor = Multiplication.multiplyByTenPow(scaledDivisor, (int)diffScale);
1100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else if (diffScale < 0) {
1101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Multiply 'u1'  by:  10^(scale - (s1 - s2))
1102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            scaledDividend  = Multiplication.multiplyByTenPow(scaledDividend, (int)-diffScale);
1103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return divideBigIntegers(scaledDividend, scaledDivisor, scale, roundingMode);
1105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
11067cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson
1107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static BigDecimal divideBigIntegers(BigInteger scaledDividend, BigInteger scaledDivisor, int scale, RoundingMode roundingMode) {
11087cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson
1109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        BigInteger[] quotAndRem = scaledDividend.divideAndRemainder(scaledDivisor);  // quotient and remainder
1110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // If after division there is a remainder...
1111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        BigInteger quotient = quotAndRem[0];
1112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        BigInteger remainder = quotAndRem[1];
1113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (remainder.signum() == 0) {
1114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return new BigDecimal(quotient, scale);
1115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int sign = scaledDividend.signum() * scaledDivisor.signum();
1117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int compRem;                                      // 'compare to remainder'
1118b5bde2fd72189192b52e726a2d606d70c3c8a34bElliott Hughes        if(scaledDivisor.bitLength() < 63) { // 63 in order to avoid out of long after *2
1119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long rem = remainder.longValue();
1120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long divisor = scaledDivisor.longValue();
1121b5bde2fd72189192b52e726a2d606d70c3c8a34bElliott Hughes            compRem = longCompareTo(Math.abs(rem) * 2,Math.abs(divisor));
1122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // To look if there is a carry
1123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            compRem = roundingBehavior(quotient.testBit(0) ? 1 : 0,
1124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    sign * (5 + compRem), roundingMode);
11257cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson
1126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
11277cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson            // Checking if:  remainder * 2 >= scaledDivisor
11287cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson            compRem = remainder.abs().shiftLeftOneBit().compareTo(scaledDivisor.abs());
1129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            compRem = roundingBehavior(quotient.testBit(0) ? 1 : 0,
1130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    sign * (5 + compRem), roundingMode);
1131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (compRem != 0) {
1133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if(quotient.bitLength() < 63) {
1134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return valueOf(quotient.longValue() + compRem,scale);
1135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            quotient = quotient.add(BigInteger.valueOf(compRem));
1137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return new BigDecimal(quotient, scale);
1138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Constructing the result with the appropriate unscaled value
1140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return new BigDecimal(quotient, scale);
1141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
11427cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson
1143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static BigDecimal dividePrimitiveLongs(long scaledDividend, long scaledDivisor, int scale, RoundingMode roundingMode) {
1144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long quotient = scaledDividend / scaledDivisor;
1145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long remainder = scaledDividend % scaledDivisor;
1146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int sign = Long.signum( scaledDividend ) * Long.signum( scaledDivisor );
1147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (remainder != 0) {
1148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Checking if:  remainder * 2 >= scaledDivisor
1149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int compRem;                                      // 'compare to remainder'
1150b5bde2fd72189192b52e726a2d606d70c3c8a34bElliott Hughes            compRem = longCompareTo(Math.abs(remainder) * 2,Math.abs(scaledDivisor));
1151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // To look if there is a carry
1152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            quotient += roundingBehavior(((int)quotient) & 1,
1153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    sign * (5 + compRem),
1154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    roundingMode);
1155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Constructing the result with the appropriate unscaled value
1157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return valueOf(quotient, scale);
1158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new {@code BigDecimal} whose value is {@code this / divisor}.
1162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The scale of the result is the scale of {@code this}. If rounding is
1163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * required to meet the specified scale, then the specified rounding mode
1164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code roundingMode} is applied.
11657cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
1166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param divisor
1167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            value by which {@code this} is divided.
1168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param roundingMode
1169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            rounding mode to be used to round the result.
1170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code this / divisor} rounded according to the given rounding
1171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         mode.
1172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
1173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code divisor == null}.
1174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
1175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code roundingMode} is not a valid rounding mode.
1176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
1177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code divisor == 0}.
1178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
1179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code roundingMode == ROUND_UNNECESSARY} and rounding is
1180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             necessary according to the scale of this.
1181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal divide(BigDecimal divisor, int roundingMode) {
1183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return divide(divisor, scale, RoundingMode.valueOf(roundingMode));
1184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new {@code BigDecimal} whose value is {@code this / divisor}.
1188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The scale of the result is the scale of {@code this}. If rounding is
1189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * required to meet the specified scale, then the specified rounding mode
1190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code roundingMode} is applied.
11917cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
1192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param divisor
1193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            value by which {@code this} is divided.
1194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param roundingMode
1195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            rounding mode to be used to round the result.
1196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code this / divisor} rounded according to the given rounding
1197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         mode.
1198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
1199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code divisor == null} or {@code roundingMode == null}.
1200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
1201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code divisor == 0}.
1202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
1203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code roundingMode == RoundingMode.UNNECESSARY} and
1204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             rounding is necessary according to the scale of this.
1205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal divide(BigDecimal divisor, RoundingMode roundingMode) {
1207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return divide(divisor, scale, roundingMode);
1208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new {@code BigDecimal} whose value is {@code this / divisor}.
1212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The scale of the result is the difference of the scales of {@code this}
1213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * and {@code divisor}. If the exact result requires more digits, then the
1214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * scale is adjusted accordingly. For example, {@code 1/128 = 0.0078125}
1215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * which has a scale of {@code 7} and precision {@code 5}.
12167cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
1217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param divisor
1218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            value by which {@code this} is divided.
1219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code this / divisor}.
1220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
1221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code divisor == null}.
1222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
1223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code divisor == 0}.
1224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
1225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the result cannot be represented exactly.
1226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal divide(BigDecimal divisor) {
1228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        BigInteger p = this.getUnscaledValue();
1229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        BigInteger q = divisor.getUnscaledValue();
1230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        BigInteger gcd; // greatest common divisor between 'p' and 'q'
1231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        BigInteger quotAndRem[];
1232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long diffScale = (long)scale - divisor.scale;
1233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int newScale; // the new scale for final quotient
1234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int k; // number of factors "2" in 'q'
1235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int l = 0; // number of factors "5" in 'q'
1236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int i = 1;
1237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int lastPow = FIVE_POW.length - 1;
1238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (divisor.isZero()) {
12408454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes            throw new ArithmeticException("Division by zero");
1241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (p.signum() == 0) {
1243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return zeroScaledBy(diffScale);
1244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // To divide both by the GCD
1246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        gcd = p.gcd(q);
1247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        p = p.divide(gcd);
1248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        q = q.divide(gcd);
1249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // To simplify all "2" factors of q, dividing by 2^k
1250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        k = q.getLowestSetBit();
1251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        q = q.shiftRight(k);
1252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // To simplify all "5" factors of q, dividing by 5^l
1253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        do {
1254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            quotAndRem = q.divideAndRemainder(FIVE_POW[i]);
1255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (quotAndRem[1].signum() == 0) {
1256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                l += i;
1257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (i < lastPow) {
1258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    i++;
1259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                q = quotAndRem[0];
1261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else {
1262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (i == 1) {
1263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    break;
1264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                i = 1;
1266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } while (true);
1268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // If  abs(q) != 1  then the quotient is periodic
1269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!q.abs().equals(BigInteger.ONE)) {
12708454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes            throw new ArithmeticException("Non-terminating decimal expansion; no exact representable decimal result");
1271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // The sign of the is fixed and the quotient will be saved in 'p'
1273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (q.signum() < 0) {
1274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            p = p.negate();
1275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Checking if the new scale is out of range
12772850a53dfbd0c172aedaec3493aad572a5ec023dJesse Wilson        newScale = safeLongToInt(diffScale + Math.max(k, l));
1278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // k >= 0  and  l >= 0  implies that  k - l  is in the 32-bit range
1279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        i = k - l;
12807cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson
1281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        p = (i > 0) ? Multiplication.multiplyByFivePow(p, i)
1282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        : p.shiftLeft(-i);
1283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return new BigDecimal(p, newScale);
1284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new {@code BigDecimal} whose value is {@code this / divisor}.
1288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The result is rounded according to the passed context {@code mc}. If the
1289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * passed math context specifies precision {@code 0}, then this call is
1290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * equivalent to {@code this.divide(divisor)}.
12917cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
1292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param divisor
1293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            value by which {@code this} is divided.
1294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param mc
1295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            rounding mode and precision for the result of this operation.
1296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code this / divisor}.
1297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
1298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code divisor == null} or {@code mc == null}.
1299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
1300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code divisor == 0}.
1301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
1302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code mc.getRoundingMode() == UNNECESSARY} and rounding
1303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             is necessary according {@code mc.getPrecision()}.
1304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal divide(BigDecimal divisor, MathContext mc) {
1306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /* Calculating how many zeros must be append to 'dividend'
1307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * to obtain a  quotient with at least 'mc.precision()' digits */
1308e866b788d613e0566b85b799fff998a09371520fJesse Wilson        long trailingZeros = mc.getPrecision() + 2L
1309e866b788d613e0566b85b799fff998a09371520fJesse Wilson                + divisor.approxPrecision() - approxPrecision();
1310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long diffScale = (long)scale - divisor.scale;
1311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long newScale = diffScale; // scale of the final quotient
1312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int compRem; // to compare the remainder
13137cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson        int i = 1; // index
1314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int lastPow = TEN_POW.length - 1; // last power of ten
1315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        BigInteger integerQuot; // for temporal results
1316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        BigInteger quotAndRem[] = {getUnscaledValue()};
1317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // In special cases it reduces the problem to call the dual method
1318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((mc.getPrecision() == 0) || (this.isZero())
1319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        || (divisor.isZero())) {
1320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return this.divide(divisor);
1321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1322e866b788d613e0566b85b799fff998a09371520fJesse Wilson        if (trailingZeros > 0) {
1323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // To append trailing zeros at end of dividend
1324e866b788d613e0566b85b799fff998a09371520fJesse Wilson            quotAndRem[0] = getUnscaledValue().multiply( Multiplication.powerOf10(trailingZeros) );
1325e866b788d613e0566b85b799fff998a09371520fJesse Wilson            newScale += trailingZeros;
1326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        quotAndRem = quotAndRem[0].divideAndRemainder( divisor.getUnscaledValue() );
1328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        integerQuot = quotAndRem[0];
1329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Calculating the exact quotient with at least 'mc.precision()' digits
1330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (quotAndRem[1].signum() != 0) {
1331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Checking if:   2 * remainder >= divisor ?
13327cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson            compRem = quotAndRem[1].shiftLeftOneBit().compareTo( divisor.getUnscaledValue() );
1333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // quot := quot * 10 + r;     with 'r' in {-6,-5,-4, 0,+4,+5,+6}
1334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            integerQuot = integerQuot.multiply(BigInteger.TEN)
1335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            .add(BigInteger.valueOf(quotAndRem[0].signum() * (5 + compRem)));
1336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            newScale++;
1337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
1338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // To strip trailing zeros until the preferred scale is reached
1339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            while (!integerQuot.testBit(0)) {
1340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                quotAndRem = integerQuot.divideAndRemainder(TEN_POW[i]);
1341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if ((quotAndRem[1].signum() == 0)
1342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        && (newScale - i >= diffScale)) {
1343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    newScale -= i;
1344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (i < lastPow) {
1345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        i++;
1346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
1347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    integerQuot = quotAndRem[0];
1348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else {
1349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (i == 1) {
1350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        break;
1351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
1352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    i = 1;
1353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // To perform rounding
13572850a53dfbd0c172aedaec3493aad572a5ec023dJesse Wilson        return new BigDecimal(integerQuot, safeLongToInt(newScale), mc);
1358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new {@code BigDecimal} whose value is the integral part of
1362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code this / divisor}. The quotient is rounded down towards zero to the
1363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * next integer. For example, {@code 0.5/0.2 = 2}.
13647cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
1365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param divisor
1366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            value by which {@code this} is divided.
1367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return integral part of {@code this / divisor}.
1368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
1369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code divisor == null}.
1370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
1371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code divisor == 0}.
1372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal divideToIntegralValue(BigDecimal divisor) {
1374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        BigInteger integralValue; // the integer of result
1375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        BigInteger powerOfTen; // some power of ten
1376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        BigInteger quotAndRem[] = {getUnscaledValue()};
1377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long newScale = (long)this.scale - divisor.scale;
1378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long tempScale = 0;
1379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int i = 1;
1380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int lastPow = TEN_POW.length - 1;
1381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (divisor.isZero()) {
13838454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes            throw new ArithmeticException("Division by zero");
1384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1385e866b788d613e0566b85b799fff998a09371520fJesse Wilson        if ((divisor.approxPrecision() + newScale > this.approxPrecision() + 1L)
1386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        || (this.isZero())) {
1387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            /* If the divisor's integer part is greater than this's integer part,
1388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project             * the result must be zero with the appropriate scale */
1389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            integralValue = BigInteger.ZERO;
1390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else if (newScale == 0) {
1391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            integralValue = getUnscaledValue().divide( divisor.getUnscaledValue() );
1392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else if (newScale > 0) {
1393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            powerOfTen = Multiplication.powerOf10(newScale);
1394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            integralValue = getUnscaledValue().divide( divisor.getUnscaledValue().multiply(powerOfTen) );
1395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            integralValue = integralValue.multiply(powerOfTen);
1396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {// (newScale < 0)
1397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            powerOfTen = Multiplication.powerOf10(-newScale);
1398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            integralValue = getUnscaledValue().multiply(powerOfTen).divide( divisor.getUnscaledValue() );
1399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // To strip trailing zeros approximating to the preferred scale
1400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            while (!integralValue.testBit(0)) {
1401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                quotAndRem = integralValue.divideAndRemainder(TEN_POW[i]);
1402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if ((quotAndRem[1].signum() == 0)
1403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        && (tempScale - i >= newScale)) {
1404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    tempScale -= i;
1405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (i < lastPow) {
1406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        i++;
1407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
1408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    integralValue = quotAndRem[0];
1409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else {
1410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (i == 1) {
1411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        break;
1412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
1413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    i = 1;
1414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            newScale = tempScale;
1417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return ((integralValue.signum() == 0)
1419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ? zeroScaledBy(newScale)
14202850a53dfbd0c172aedaec3493aad572a5ec023dJesse Wilson                : new BigDecimal(integralValue, safeLongToInt(newScale)));
1421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new {@code BigDecimal} whose value is the integral part of
1425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code this / divisor}. The quotient is rounded down towards zero to the
1426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * next integer. The rounding mode passed with the parameter {@code mc} is
1427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * not considered. But if the precision of {@code mc > 0} and the integral
1428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * part requires more digits, then an {@code ArithmeticException} is thrown.
14297cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
1430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param divisor
1431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            value by which {@code this} is divided.
1432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param mc
1433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            math context which determines the maximal precision of the
1434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            result.
1435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return integral part of {@code this / divisor}.
1436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
1437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code divisor == null} or {@code mc == null}.
1438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
1439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code divisor == 0}.
1440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
1441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code mc.getPrecision() > 0} and the result requires more
1442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             digits to be represented.
1443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal divideToIntegralValue(BigDecimal divisor, MathContext mc) {
1445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int mcPrecision = mc.getPrecision();
1446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int diffPrecision = this.precision() - divisor.precision();
1447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int lastPow = TEN_POW.length - 1;
1448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long diffScale = (long)this.scale - divisor.scale;
1449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long newScale = diffScale;
1450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long quotPrecision = diffPrecision - diffScale + 1;
1451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        BigInteger quotAndRem[] = new BigInteger[2];
1452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // In special cases it call the dual method
1453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((mcPrecision == 0) || (this.isZero()) || (divisor.isZero())) {
1454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return this.divideToIntegralValue(divisor);
1455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Let be:   this = [u1,s1]   and   divisor = [u2,s2]
1457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (quotPrecision <= 0) {
1458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            quotAndRem[0] = BigInteger.ZERO;
1459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else if (diffScale == 0) {
14607cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson            // CASE s1 == s2:  to calculate   u1 / u2
1461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            quotAndRem[0] = this.getUnscaledValue().divide( divisor.getUnscaledValue() );
1462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else if (diffScale > 0) {
14637cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson            // CASE s1 >= s2:  to calculate   u1 / (u2 * 10^(s1-s2)
1464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            quotAndRem[0] = this.getUnscaledValue().divide(
1465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    divisor.getUnscaledValue().multiply(Multiplication.powerOf10(diffScale)) );
1466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // To chose  10^newScale  to get a quotient with at least 'mc.precision()' digits
1467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            newScale = Math.min(diffScale, Math.max(mcPrecision - quotPrecision + 1, 0));
1468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // To calculate: (u1 / (u2 * 10^(s1-s2)) * 10^newScale
1469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            quotAndRem[0] = quotAndRem[0].multiply(Multiplication.powerOf10(newScale));
14707cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson        } else {// CASE s2 > s1:
14717cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson            /* To calculate the minimum power of ten, such that the quotient
1472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project             *   (u1 * 10^exp) / u2   has at least 'mc.precision()' digits. */
1473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long exp = Math.min(-diffScale, Math.max((long)mcPrecision - diffPrecision, 0));
1474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long compRemDiv;
14757cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson            // Let be:   (u1 * 10^exp) / u2 = [q,r]
1476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            quotAndRem = this.getUnscaledValue().multiply(Multiplication.powerOf10(exp)).
1477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    divideAndRemainder(divisor.getUnscaledValue());
1478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            newScale += exp; // To fix the scale
1479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            exp = -newScale; // The remaining power of ten
1480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // If after division there is a remainder...
1481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if ((quotAndRem[1].signum() != 0) && (exp > 0)) {
1482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // Log10(r) + ((s2 - s1) - exp) > mc.precision ?
1483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                compRemDiv = (new BigDecimal(quotAndRem[1])).precision()
1484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                + exp - divisor.precision();
1485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (compRemDiv == 0) {
1486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // To calculate:  (r * 10^exp2) / u2
1487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    quotAndRem[1] = quotAndRem[1].multiply(Multiplication.powerOf10(exp)).
1488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            divide(divisor.getUnscaledValue());
1489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    compRemDiv = Math.abs(quotAndRem[1].signum());
1490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (compRemDiv > 0) {
14928454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes                    throw new ArithmeticException("Division impossible");
1493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Fast return if the quotient is zero
1497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (quotAndRem[0].signum() == 0) {
1498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return zeroScaledBy(diffScale);
1499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        BigInteger strippedBI = quotAndRem[0];
1501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        BigDecimal integralValue = new BigDecimal(quotAndRem[0]);
1502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long resultPrecision = integralValue.precision();
1503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int i = 1;
1504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // To strip trailing zeros until the specified precision is reached
1505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        while (!strippedBI.testBit(0)) {
1506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            quotAndRem = strippedBI.divideAndRemainder(TEN_POW[i]);
1507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if ((quotAndRem[1].signum() == 0) &&
1508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    ((resultPrecision - i >= mcPrecision)
1509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    || (newScale - i >= diffScale)) ) {
1510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                resultPrecision -= i;
1511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                newScale -= i;
1512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (i < lastPow) {
1513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    i++;
1514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                strippedBI = quotAndRem[0];
1516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else {
1517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (i == 1) {
1518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    break;
1519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                i = 1;
1521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // To check if the result fit in 'mc.precision()' digits
1524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (resultPrecision > mcPrecision) {
15258454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes            throw new ArithmeticException("Division impossible");
1526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
15272850a53dfbd0c172aedaec3493aad572a5ec023dJesse Wilson        integralValue.scale = safeLongToInt(newScale);
1528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        integralValue.setUnscaledValue(strippedBI);
1529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return integralValue;
1530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new {@code BigDecimal} whose value is {@code this % divisor}.
1534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
1535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The remainder is defined as {@code this -
1536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * this.divideToIntegralValue(divisor) * divisor}.
15377cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
1538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param divisor
1539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            value by which {@code this} is divided.
1540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code this % divisor}.
1541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
1542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code divisor == null}.
1543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
1544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code divisor == 0}.
1545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal remainder(BigDecimal divisor) {
1547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return divideAndRemainder(divisor)[1];
1548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new {@code BigDecimal} whose value is {@code this % divisor}.
1552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
1553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The remainder is defined as {@code this -
1554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * this.divideToIntegralValue(divisor) * divisor}.
1555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
1556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The specified rounding mode {@code mc} is used for the division only.
15577cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
1558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param divisor
1559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            value by which {@code this} is divided.
1560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param mc
1561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            rounding mode and precision to be used.
1562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code this % divisor}.
1563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
1564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code divisor == null}.
1565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
1566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code divisor == 0}.
1567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
1568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code mc.getPrecision() > 0} and the result of {@code
1569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             this.divideToIntegralValue(divisor, mc)} requires more digits
1570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             to be represented.
1571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal remainder(BigDecimal divisor, MathContext mc) {
1573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return divideAndRemainder(divisor, mc)[1];
1574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a {@code BigDecimal} array which contains the integral part of
1578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code this / divisor} at index 0 and the remainder {@code this %
1579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * divisor} at index 1. The quotient is rounded down towards zero to the
1580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * next integer.
15817cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
1582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param divisor
1583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            value by which {@code this} is divided.
1584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code [this.divideToIntegralValue(divisor),
1585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         this.remainder(divisor)]}.
1586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
1587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code divisor == null}.
1588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
1589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code divisor == 0}.
1590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #divideToIntegralValue
1591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #remainder
1592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal[] divideAndRemainder(BigDecimal divisor) {
1594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        BigDecimal quotAndRem[] = new BigDecimal[2];
1595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        quotAndRem[0] = this.divideToIntegralValue(divisor);
1597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        quotAndRem[1] = this.subtract( quotAndRem[0].multiply(divisor) );
1598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return quotAndRem;
1599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a {@code BigDecimal} array which contains the integral part of
1603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code this / divisor} at index 0 and the remainder {@code this %
1604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * divisor} at index 1. The quotient is rounded down towards zero to the
1605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * next integer. The rounding mode passed with the parameter {@code mc} is
1606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * not considered. But if the precision of {@code mc > 0} and the integral
1607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * part requires more digits, then an {@code ArithmeticException} is thrown.
16087cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
1609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param divisor
1610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            value by which {@code this} is divided.
1611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param mc
1612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            math context which determines the maximal precision of the
1613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            result.
1614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code [this.divideToIntegralValue(divisor),
1615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         this.remainder(divisor)]}.
1616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
1617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code divisor == null}.
1618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
1619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code divisor == 0}.
1620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #divideToIntegralValue
1621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #remainder
1622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal[] divideAndRemainder(BigDecimal divisor, MathContext mc) {
1624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        BigDecimal quotAndRem[] = new BigDecimal[2];
1625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        quotAndRem[0] = this.divideToIntegralValue(divisor, mc);
1627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        quotAndRem[1] = this.subtract( quotAndRem[0].multiply(divisor) );
1628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return quotAndRem;
1629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new {@code BigDecimal} whose value is {@code this ^ n}. The
1633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * scale of the result is {@code n} times the scales of {@code this}.
1634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
1635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code x.pow(0)} returns {@code 1}, even if {@code x == 0}.
1636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
1637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Implementation Note: The implementation is based on the ANSI standard
1638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * X3.274-1996 algorithm.
16397cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
1640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param n
1641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            exponent to which {@code this} is raised.
1642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code this ^ n}.
1643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
1644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code n < 0} or {@code n > 999999999}.
1645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal pow(int n) {
1647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (n == 0) {
1648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return ONE;
1649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((n < 0) || (n > 999999999)) {
16518454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes            throw new ArithmeticException("Invalid operation");
1652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long newScale = scale * (long)n;
1654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Let be: this = [u,s]   so:  this^n = [u^n, s*n]
16558454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes        return isZero() ? zeroScaledBy(newScale)
16562850a53dfbd0c172aedaec3493aad572a5ec023dJesse Wilson                : new BigDecimal(getUnscaledValue().pow(n), safeLongToInt(newScale));
1657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new {@code BigDecimal} whose value is {@code this ^ n}. The
1661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * result is rounded according to the passed context {@code mc}.
1662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
1663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Implementation Note: The implementation is based on the ANSI standard
1664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * X3.274-1996 algorithm.
16657cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
1666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param n
1667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            exponent to which {@code this} is raised.
1668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param mc
1669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            rounding mode and precision for the result of this operation.
1670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code this ^ n}.
1671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
1672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code n < 0} or {@code n > 999999999}.
1673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal pow(int n, MathContext mc) {
1675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // The ANSI standard X3.274-1996 algorithm
1676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int m = Math.abs(n);
1677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int mcPrecision = mc.getPrecision();
1678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int elength = (int)Math.log10(m) + 1;   // decimal digits in 'n'
1679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int oneBitMask; // mask of bits
1680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        BigDecimal accum; // the single accumulator
1681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        MathContext newPrecision = mc; // MathContext by default
1682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // In particular cases, it reduces the problem to call the other 'pow()'
1684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((n == 0) || ((isZero()) && (n > 0))) {
1685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return pow(n);
1686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((m > 999999999) || ((mcPrecision == 0) && (n < 0))
1688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                || ((mcPrecision > 0) && (elength > mcPrecision))) {
16898454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes            throw new ArithmeticException("Invalid operation");
1690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (mcPrecision > 0) {
1692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            newPrecision = new MathContext( mcPrecision + elength + 1,
1693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    mc.getRoundingMode());
1694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
16957cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson        // The result is calculated as if 'n' were positive
1696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        accum = round(newPrecision);
1697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        oneBitMask = Integer.highestOneBit(m) >> 1;
1698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        while (oneBitMask > 0) {
1700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            accum = accum.multiply(accum, newPrecision);
1701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if ((m & oneBitMask) == oneBitMask) {
1702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                accum = accum.multiply(this, newPrecision);
1703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            oneBitMask >>= 1;
1705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // If 'n' is negative, the value is divided into 'ONE'
1707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (n < 0) {
1708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            accum = ONE.divide(accum, newPrecision);
1709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // The final value is rounded to the destination precision
1711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        accum.inplaceRound(mc);
1712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return accum;
1713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new {@code BigDecimal} whose value is the absolute value of
1717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code this}. The scale of the result is the same as the scale of this.
17187cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
1719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code abs(this)}
1720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal abs() {
1722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return ((signum() < 0) ? negate() : this);
1723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new {@code BigDecimal} whose value is the absolute value of
1727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code this}. The result is rounded according to the passed context
1728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code mc}.
17297cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
1730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param mc
1731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            rounding mode and precision for the result of this operation.
1732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code abs(this)}
1733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal abs(MathContext mc) {
1735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        BigDecimal result = abs();
1736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        result.inplaceRound(mc);
1737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result;
1738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new {@code BigDecimal} whose value is the {@code -this}. The
1742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * scale of the result is the same as the scale of this.
17437cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
1744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code -this}
1745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal negate() {
1747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if(bitLength < 63 || (bitLength == 63 && smallValue!=Long.MIN_VALUE)) {
1748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return valueOf(-smallValue,scale);
1749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return new BigDecimal(getUnscaledValue().negate(), scale);
1751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new {@code BigDecimal} whose value is the {@code -this}. The
1755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * result is rounded according to the passed context {@code mc}.
17567cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
1757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param mc
1758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            rounding mode and precision for the result of this operation.
1759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code -this}
1760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal negate(MathContext mc) {
1762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        BigDecimal result = negate();
1763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        result.inplaceRound(mc);
1764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result;
1765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1768adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new {@code BigDecimal} whose value is {@code +this}. The scale
1769adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * of the result is the same as the scale of this.
17707cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
1771adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code this}
1772adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal plus() {
1774adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return this;
1775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1778adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new {@code BigDecimal} whose value is {@code +this}. The result
1779adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * is rounded according to the passed context {@code mc}.
17807cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
1781adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param mc
1782adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            rounding mode and precision for the result of this operation.
17837cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     * @return {@code this}, rounded
1784adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1785adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal plus(MathContext mc) {
1786adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return round(mc);
1787adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1788adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1789adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1790adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the sign of this {@code BigDecimal}.
17917cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
17927cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     * @return {@code -1} if {@code this < 0},
1793adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code 0} if {@code this == 0},
17947cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *         {@code 1} if {@code this > 0}.     */
1795adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int signum() {
1796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if( bitLength < 64) {
1797adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return Long.signum( this.smallValue );
1798adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1799adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return getUnscaledValue().signum();
1800adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
18017cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson
1802adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean isZero() {
1803adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //Watch out: -1 has a bitLength=0
1804adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return bitLength == 0 && this.smallValue != -1;
1805adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1806adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1808adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the scale of this {@code BigDecimal}. The scale is the number of
1809adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * digits behind the decimal point. The value of this {@code BigDecimal} is
1810adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the unsignedValue * 10^(-scale). If the scale is negative, then this
1811adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code BigDecimal} represents a big integer.
18127cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
1813adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the scale of this {@code BigDecimal}.
1814adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1815adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int scale() {
1816adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return scale;
1817adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1818adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1819adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1820adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the precision of this {@code BigDecimal}. The precision is the
1821adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * number of decimal digits used to represent this decimal. It is equivalent
1822adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * to the number of digits of the unscaled value. The precision of {@code 0}
1823adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * is {@code 1} (independent of the scale).
18247cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
1825adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the precision of this {@code BigDecimal}.
1826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1827adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int precision() {
1828adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Checking if the precision already was calculated
1829adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (precision > 0) {
1830adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return precision;
1831adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1832e866b788d613e0566b85b799fff998a09371520fJesse Wilson
1833adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int bitLength = this.bitLength;
1834e866b788d613e0566b85b799fff998a09371520fJesse Wilson
1835e866b788d613e0566b85b799fff998a09371520fJesse Wilson        if (bitLength == 0) {
1836e866b788d613e0566b85b799fff998a09371520fJesse Wilson            precision = 1;
1837e866b788d613e0566b85b799fff998a09371520fJesse Wilson        } else if (bitLength < 64) {
1838e866b788d613e0566b85b799fff998a09371520fJesse Wilson            precision = decimalDigitsInLong(smallValue);
1839e866b788d613e0566b85b799fff998a09371520fJesse Wilson        } else {
1840e866b788d613e0566b85b799fff998a09371520fJesse Wilson            int decimalDigits = 1 + (int) ((bitLength - 1) * LOG10_2);
1841e866b788d613e0566b85b799fff998a09371520fJesse Wilson            // If after division the number isn't zero, there exists an additional digit
1842adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (getUnscaledValue().divide(Multiplication.powerOf10(decimalDigits)).signum() != 0) {
1843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                decimalDigits++;
1844adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1845e866b788d613e0566b85b799fff998a09371520fJesse Wilson            precision = decimalDigits;
1846adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1847adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return precision;
1848adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1849adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1850e866b788d613e0566b85b799fff998a09371520fJesse Wilson    private int decimalDigitsInLong(long value) {
1851e866b788d613e0566b85b799fff998a09371520fJesse Wilson        if (value == Long.MIN_VALUE) {
1852e866b788d613e0566b85b799fff998a09371520fJesse Wilson            return 19; // special case required because abs(MIN_VALUE) == MIN_VALUE
1853e866b788d613e0566b85b799fff998a09371520fJesse Wilson        } else {
1854706de1164836051ab31cc69eb77a6bba1a723896Elliott Hughes            int index = Arrays.binarySearch(MathUtils.LONG_POWERS_OF_TEN, Math.abs(value));
1855e866b788d613e0566b85b799fff998a09371520fJesse Wilson            return (index < 0) ? (-index - 1) : (index + 1);
1856e866b788d613e0566b85b799fff998a09371520fJesse Wilson        }
1857e866b788d613e0566b85b799fff998a09371520fJesse Wilson    }
1858e866b788d613e0566b85b799fff998a09371520fJesse Wilson
1859adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1860adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the unscaled value (mantissa) of this {@code BigDecimal} instance
1861adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * as a {@code BigInteger}. The unscaled value can be computed as {@code
1862adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * this} 10^(scale).
18637cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
1864adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return unscaled value (this * 10^(scale)).
1865adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1866adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigInteger unscaledValue() {
1867adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return getUnscaledValue();
1868adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1869adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1870adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1871adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new {@code BigDecimal} whose value is {@code this}, rounded
1872adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * according to the passed context {@code mc}.
1873adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
1874adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * If {@code mc.precision = 0}, then no rounding is performed.
1875adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
1876adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * If {@code mc.precision > 0} and {@code mc.roundingMode == UNNECESSARY},
1877adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * then an {@code ArithmeticException} is thrown if the result cannot be
1878adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * represented exactly within the given precision.
18797cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
1880adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param mc
1881adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            rounding mode and precision for the result of this operation.
1882adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code this} rounded according to the passed context.
1883adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
1884adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code mc.precision > 0} and {@code mc.roundingMode ==
1885adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             UNNECESSARY} and this cannot be represented within the given
1886adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             precision.
1887adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1888adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal round(MathContext mc) {
1889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        BigDecimal thisBD = new BigDecimal(getUnscaledValue(), scale);
1890adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1891adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        thisBD.inplaceRound(mc);
1892adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return thisBD;
1893adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1894adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1895adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1896adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new {@code BigDecimal} instance with the specified scale.
1897adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
1898adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * If the new scale is greater than the old scale, then additional zeros are
1899adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * added to the unscaled value. In this case no rounding is necessary.
1900adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
1901adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * If the new scale is smaller than the old scale, then trailing digits are
1902adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * removed. If these trailing digits are not zero, then the remaining
1903adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * unscaled value has to be rounded. For this rounding operation the
1904adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * specified rounding mode is used.
19057cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
1906adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param newScale
1907adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            scale of the result returned.
1908adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param roundingMode
1909adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            rounding mode to be used to round the result.
1910adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a new {@code BigDecimal} instance with the specified scale.
1911adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
1912adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code roundingMode == null}.
1913adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
1914adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code roundingMode == ROUND_UNNECESSARY} and rounding is
1915adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             necessary according to the given scale.
1916adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1917adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal setScale(int newScale, RoundingMode roundingMode) {
1918adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (roundingMode == null) {
191986acc043d3334651ee26c65467d78d6cefedd397Kenny Root            throw new NullPointerException("roundingMode == null");
1920adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1921adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long diffScale = newScale - (long)scale;
19227cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson        // Let be:  'this' = [u,s]
1923adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if(diffScale == 0) {
1924adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return this;
1925adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1926adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if(diffScale > 0) {
1927adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // return  [u * 10^(s2 - s), newScale]
1928706de1164836051ab31cc69eb77a6bba1a723896Elliott Hughes            if(diffScale < MathUtils.LONG_POWERS_OF_TEN.length &&
1929706de1164836051ab31cc69eb77a6bba1a723896Elliott Hughes                    (this.bitLength + LONG_POWERS_OF_TEN_BIT_LENGTH[(int)diffScale]) < 64 ) {
1930706de1164836051ab31cc69eb77a6bba1a723896Elliott Hughes                return valueOf(this.smallValue*MathUtils.LONG_POWERS_OF_TEN[(int)diffScale],newScale);
1931adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1932adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return new BigDecimal(Multiplication.multiplyByTenPow(getUnscaledValue(),(int)diffScale), newScale);
1933adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1934adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // diffScale < 0
1935adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // return  [u,s] / [1,newScale]  with the appropriate scale and rounding
1936706de1164836051ab31cc69eb77a6bba1a723896Elliott Hughes        if(this.bitLength < 64 && -diffScale < MathUtils.LONG_POWERS_OF_TEN.length) {
1937706de1164836051ab31cc69eb77a6bba1a723896Elliott Hughes            return dividePrimitiveLongs(this.smallValue, MathUtils.LONG_POWERS_OF_TEN[(int)-diffScale], newScale,roundingMode);
1938adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1939adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return divideBigIntegers(this.getUnscaledValue(),Multiplication.powerOf10(-diffScale),newScale,roundingMode);
1940adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1941adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1942adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1943adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new {@code BigDecimal} instance with the specified scale.
1944adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
1945adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * If the new scale is greater than the old scale, then additional zeros are
1946adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * added to the unscaled value. In this case no rounding is necessary.
1947adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
1948adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * If the new scale is smaller than the old scale, then trailing digits are
1949adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * removed. If these trailing digits are not zero, then the remaining
1950adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * unscaled value has to be rounded. For this rounding operation the
1951adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * specified rounding mode is used.
19527cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
1953adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param newScale
1954adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            scale of the result returned.
1955adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param roundingMode
1956adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            rounding mode to be used to round the result.
1957adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a new {@code BigDecimal} instance with the specified scale.
1958adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
1959adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code roundingMode} is not a valid rounding mode.
1960adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
1961adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code roundingMode == ROUND_UNNECESSARY} and rounding is
1962adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             necessary according to the given scale.
1963adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1964adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal setScale(int newScale, int roundingMode) {
1965adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return setScale(newScale, RoundingMode.valueOf(roundingMode));
1966adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1967adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1968adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1969adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new {@code BigDecimal} instance with the specified scale. If
1970adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the new scale is greater than the old scale, then additional zeros are
1971adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * added to the unscaled value. If the new scale is smaller than the old
1972adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * scale, then trailing zeros are removed. If the trailing digits are not
1973adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * zeros then an ArithmeticException is thrown.
1974adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
1975adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * If no exception is thrown, then the following equation holds: {@code
1976adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * x.setScale(s).compareTo(x) == 0}.
19777cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
1978adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param newScale
1979adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            scale of the result returned.
1980adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a new {@code BigDecimal} instance with the specified scale.
1981adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
1982adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if rounding would be necessary.
1983adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1984adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal setScale(int newScale) {
1985adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return setScale(newScale, RoundingMode.UNNECESSARY);
1986adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1987adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1988adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1989adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new {@code BigDecimal} instance where the decimal point has
1990adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * been moved {@code n} places to the left. If {@code n < 0} then the
1991adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * decimal point is moved {@code -n} places to the right.
1992adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
1993adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The result is obtained by changing its scale. If the scale of the result
1994adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * becomes negative, then its precision is increased such that the scale is
1995adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * zero.
1996adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
1997adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Note, that {@code movePointLeft(0)} returns a result which is
1998adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * mathematically equivalent, but which has {@code scale >= 0}.
19997cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
2000adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param n
2001adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            number of placed the decimal point has to be moved.
20027cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     * @return {@code this * 10^(-n}).
2003adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2004adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal movePointLeft(int n) {
2005adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return movePoint(scale + (long)n);
2006adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2007adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2008adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private BigDecimal movePoint(long newScale) {
2009adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (isZero()) {
2010adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return zeroScaledBy(Math.max(newScale, 0));
2011adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2012adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /*
2013adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * When: 'n'== Integer.MIN_VALUE isn't possible to call to
2014adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * movePointRight(-n) since -Integer.MIN_VALUE == Integer.MIN_VALUE
2015adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
2016adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if(newScale >= 0) {
2017adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if(bitLength < 64) {
20182850a53dfbd0c172aedaec3493aad572a5ec023dJesse Wilson                return valueOf(smallValue, safeLongToInt(newScale));
2019adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
20202850a53dfbd0c172aedaec3493aad572a5ec023dJesse Wilson            return new BigDecimal(getUnscaledValue(), safeLongToInt(newScale));
2021adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2022706de1164836051ab31cc69eb77a6bba1a723896Elliott Hughes        if(-newScale < MathUtils.LONG_POWERS_OF_TEN.length &&
2023706de1164836051ab31cc69eb77a6bba1a723896Elliott Hughes                bitLength + LONG_POWERS_OF_TEN_BIT_LENGTH[(int)-newScale] < 64 ) {
2024706de1164836051ab31cc69eb77a6bba1a723896Elliott Hughes            return valueOf(smallValue*MathUtils.LONG_POWERS_OF_TEN[(int)-newScale],0);
2025adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
20262850a53dfbd0c172aedaec3493aad572a5ec023dJesse Wilson        return new BigDecimal(Multiplication.multiplyByTenPow(
20272850a53dfbd0c172aedaec3493aad572a5ec023dJesse Wilson                getUnscaledValue(), safeLongToInt(-newScale)), 0);
2028adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2029adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2030adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2031adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new {@code BigDecimal} instance where the decimal point has
2032adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * been moved {@code n} places to the right. If {@code n < 0} then the
2033adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * decimal point is moved {@code -n} places to the left.
2034adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
2035adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The result is obtained by changing its scale. If the scale of the result
2036adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * becomes negative, then its precision is increased such that the scale is
2037adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * zero.
2038adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
2039adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Note, that {@code movePointRight(0)} returns a result which is
2040adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * mathematically equivalent, but which has scale >= 0.
20417cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
2042adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param n
2043adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            number of placed the decimal point has to be moved.
20447cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     * @return {@code this * 10^n}.
2045adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2046adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal movePointRight(int n) {
2047adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return movePoint(scale - (long)n);
2048adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2049adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2050adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2051adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new {@code BigDecimal} whose value is {@code this} 10^{@code n}.
20527cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     * The scale of the result is {@code this.scale()} - {@code n}.
2053adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The precision of the result is the precision of {@code this}.
2054adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
2055adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * This method has the same effect as {@link #movePointRight}, except that
2056adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the precision is not changed.
20577cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
2058adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param n
2059adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            number of places the decimal point has to be moved.
20607cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     * @return {@code this * 10^n}
2061adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2062adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal scaleByPowerOfTen(int n) {
2063adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long newScale = scale - (long)n;
2064adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if(bitLength < 64) {
2065adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            //Taking care when a 0 is to be scaled
2066adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if( smallValue==0  ){
2067adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return zeroScaledBy( newScale );
2068adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
20692850a53dfbd0c172aedaec3493aad572a5ec023dJesse Wilson            return valueOf(smallValue, safeLongToInt(newScale));
2070adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
20712850a53dfbd0c172aedaec3493aad572a5ec023dJesse Wilson        return new BigDecimal(getUnscaledValue(), safeLongToInt(newScale));
2072adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2073adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2074adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2075adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new {@code BigDecimal} instance with the same value as {@code
2076adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * this} but with a unscaled value where the trailing zeros have been
2077adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * removed. If the unscaled value of {@code this} has n trailing zeros, then
2078adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the scale and the precision of the result has been reduced by n.
20797cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
2080adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a new {@code BigDecimal} instance equivalent to this where the
2081adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         trailing zeros of the unscaled value have been removed.
2082adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2083adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal stripTrailingZeros() {
2084adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int i = 1; // 1 <= i <= 18
2085adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int lastPow = TEN_POW.length - 1;
2086adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long newScale = scale;
2087adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2088adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (isZero()) {
2089fb0ec0e650bf8be35acb0d47da0311a7c446aa33Elliott Hughes            // Preserve RI compatibility, so BigDecimal.equals (which checks
20905c2b841724e903a06efdfb854bc2cd7c305728edElliott Hughes            // value *and* scale) continues to work.
20914b8c7d1c8812bf0f6e29d557a5794e126202133eJesse Wilson            return this;
2092adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2093adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        BigInteger strippedBI = getUnscaledValue();
2094adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        BigInteger[] quotAndRem;
20957cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson
2096adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // while the number is even...
2097adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        while (!strippedBI.testBit(0)) {
2098adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // To divide by 10^i
2099adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            quotAndRem = strippedBI.divideAndRemainder(TEN_POW[i]);
2100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // To look the remainder
2101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (quotAndRem[1].signum() == 0) {
2102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // To adjust the scale
2103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                newScale -= i;
2104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (i < lastPow) {
2105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // To set to the next power
2106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    i++;
2107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
2108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                strippedBI = quotAndRem[0];
2109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else {
2110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (i == 1) {
2111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // 'this' has no more trailing zeros
2112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    break;
2113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
2114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // To set to the smallest power of ten
2115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                i = 1;
2116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
21182850a53dfbd0c172aedaec3493aad572a5ec023dJesse Wilson        return new BigDecimal(strippedBI, safeLongToInt(newScale));
2119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Compares this {@code BigDecimal} with {@code val}. Returns one of the
2123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * three values {@code 1}, {@code 0}, or {@code -1}. The method behaves as
2124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * if {@code this.subtract(val)} is computed. If this difference is > 0 then
2125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * 1 is returned, if the difference is < 0 then -1 is returned, and if the
2126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * difference is 0 then 0 is returned. This means, that if two decimal
2127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * instances are compared which are equal in value but differ in scale, then
2128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * these two instances are considered as equal.
21297cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
2130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param val
2131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            value to be compared with {@code this}.
2132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code 1} if {@code this > val}, {@code -1} if {@code this < val},
2133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code 0} if {@code this == val}.
2134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
2135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code val == null}.
2136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int compareTo(BigDecimal val) {
2138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int thisSign = signum();
2139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int valueSign = val.signum();
2140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if( thisSign == valueSign) {
2142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if(this.scale == val.scale && this.bitLength<64 && val.bitLength<64 ) {
2143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return (smallValue < val.smallValue) ? -1 : (smallValue > val.smallValue) ? 1 : 0;
2144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long diffScale = (long)this.scale - val.scale;
2146e866b788d613e0566b85b799fff998a09371520fJesse Wilson            int diffPrecision = this.approxPrecision() - val.approxPrecision();
2147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (diffPrecision > diffScale + 1) {
2148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return thisSign;
2149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else if (diffPrecision < diffScale - 1) {
2150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return -thisSign;
2151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else {// thisSign == val.signum()  and  diffPrecision is aprox. diffScale
2152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                BigInteger thisUnscaled = this.getUnscaledValue();
2153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                BigInteger valUnscaled = val.getUnscaledValue();
2154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // If any of both precision is bigger, append zeros to the shorter one
2155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (diffScale < 0) {
2156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    thisUnscaled = thisUnscaled.multiply(Multiplication.powerOf10(-diffScale));
2157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else if (diffScale > 0) {
2158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    valUnscaled = valUnscaled.multiply(Multiplication.powerOf10(diffScale));
2159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
2160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return thisUnscaled.compareTo(valUnscaled);
2161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else if (thisSign < valueSign) {
2163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return -1;
2164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else  {
2165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return 1;
2166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns {@code true} if {@code x} is a {@code BigDecimal} instance and if
2171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * this instance is equal to this big decimal. Two big decimals are equal if
2172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * their unscaled value and their scale is equal. For example, 1.0
2173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * (10*10^(-1)) is not equal to 1.00 (100*10^(-2)). Similarly, zero
2174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * instances are not equal if their scale differs.
21757cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
2176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param x
2177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            object to be compared with {@code this}.
2178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return true if {@code x} is a {@code BigDecimal} and {@code this == x}.
2179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
21817cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson    public boolean equals(Object x) {
2182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this == x) {
2183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return true;
2184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (x instanceof BigDecimal) {
21867cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson            BigDecimal x1 = (BigDecimal) x;
21877cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson            return x1.scale == scale
2188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                   && (bitLength < 64 ? (x1.smallValue == smallValue)
2189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    : intVal.equals(x1.intVal));
21907cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson
21917cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson
21927cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson        }
21937cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson        return false;
21947cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson    }
2195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the minimum of this {@code BigDecimal} and {@code val}.
21987cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
2199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param val
2200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            value to be used to compute the minimum with this.
2201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code min(this, val}.
2202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
2203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code val == null}.
2204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal min(BigDecimal val) {
2206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return ((compareTo(val) <= 0) ? this : val);
2207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the maximum of this {@code BigDecimal} and {@code val}.
22117cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
2212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param val
2213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            value to be used to compute the maximum with this.
2214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code max(this, val}.
2215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
2216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code val == null}.
2217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal max(BigDecimal val) {
2219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return ((compareTo(val) >= 0) ? this : val);
2220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a hash code for this {@code BigDecimal}.
22247cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
2225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return hash code for {@code this}.
2226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
22287cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson    public int hashCode() {
2229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (hashCode != 0) {
2230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return hashCode;
2231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (bitLength < 64) {
2233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            hashCode = (int)(smallValue & 0xffffffff);
2234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            hashCode = 33 * hashCode +  (int)((smallValue >> 32) & 0xffffffff);
22357cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson            hashCode = 17 * hashCode + scale;
2236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return hashCode;
2237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
22387cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson        hashCode = 17 * intVal.hashCode() + scale;
22397cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson        return hashCode;
2240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a canonical string representation of this {@code BigDecimal}. If
2244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * necessary, scientific notation is used. This representation always prints
2245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * all significant digits of this value.
2246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
2247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * If the scale is negative or if {@code scale - precision >= 6} then
2248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * scientific notation is used.
22497cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
2250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a string representation of {@code this} in scientific notation if
2251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         necessary.
2252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
2254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String toString() {
2255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (toStringImage != null) {
2256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return toStringImage;
2257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if(bitLength < 32) {
2259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            toStringImage = Conversion.toDecimalScaledString(smallValue,scale);
2260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return toStringImage;
2261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String intString = getUnscaledValue().toString();
2263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (scale == 0) {
2264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return intString;
2265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int begin = (getUnscaledValue().signum() < 0) ? 2 : 1;
2267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int end = intString.length();
2268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long exponent = -(long)scale + end - begin;
22697f0c06f737b6f1f6b3a5bb30111f95dd0ca586a2Brian Carlstrom        StringBuilder result = new StringBuilder();
2270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        result.append(intString);
2272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((scale > 0) && (exponent >= -6)) {
2273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (exponent >= 0) {
2274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result.insert(end - scale, '.');
2275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else {
22768454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes                result.insert(begin - 1, "0.");
2277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result.insert(begin + 1, CH_ZEROS, 0, -(int)exponent - 1);
2278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
2280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (end - begin >= 1) {
2281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result.insert(begin, '.');
2282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                end++;
2283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            result.insert(end, 'E');
2285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (exponent > 0) {
2286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result.insert(++end, '+');
2287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            result.insert(++end, Long.toString(exponent));
2289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        toStringImage = result.toString();
2291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return toStringImage;
2292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a string representation of this {@code BigDecimal}. This
2296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * representation always prints all significant digits of this value.
2297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
2298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * If the scale is negative or if {@code scale - precision >= 6} then
2299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * engineering notation is used. Engineering notation is similar to the
2300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * scientific notation except that the exponent is made to be a multiple of
2301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * 3 such that the integer part is >= 1 and < 1000.
23027cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
2303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a string representation of {@code this} in engineering notation
2304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         if necessary.
2305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String toEngineeringString() {
2307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String intString = getUnscaledValue().toString();
2308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (scale == 0) {
2309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return intString;
2310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int begin = (getUnscaledValue().signum() < 0) ? 2 : 1;
2312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int end = intString.length();
2313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long exponent = -(long)scale + end - begin;
23147f0c06f737b6f1f6b3a5bb30111f95dd0ca586a2Brian Carlstrom        StringBuilder result = new StringBuilder(intString);
2315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((scale > 0) && (exponent >= -6)) {
2317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (exponent >= 0) {
2318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result.insert(end - scale, '.');
2319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else {
23208454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes                result.insert(begin - 1, "0.");
2321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result.insert(begin + 1, CH_ZEROS, 0, -(int)exponent - 1);
2322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
2324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int delta = end - begin;
2325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int rem = (int)(exponent % 3);
2326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (rem != 0) {
2328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // adjust exponent so it is a multiple of three
2329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (getUnscaledValue().signum() == 0) {
2330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // zero value
2331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    rem = (rem < 0) ? -rem : 3 - rem;
2332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    exponent += rem;
2333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else {
2334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // nonzero value
2335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    rem = (rem < 0) ? rem + 3 : rem;
2336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    exponent -= rem;
2337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    begin += rem;
2338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
2339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (delta < 3) {
2340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    for (int i = rem - delta; i > 0; i--) {
2341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        result.insert(end++, '0');
2342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
2343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
2344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (end - begin >= 1) {
2346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result.insert(begin, '.');
2347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                end++;
2348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (exponent != 0) {
2350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result.insert(end, 'E');
2351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (exponent > 0) {
2352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    result.insert(++end, '+');
2353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
2354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result.insert(++end, Long.toString(exponent));
2355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result.toString();
2358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a string representation of this {@code BigDecimal}. No scientific
2362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * notation is used. This methods adds zeros where necessary.
2363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
2364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * If this string representation is used to create a new instance, this
2365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * instance is generally not identical to {@code this} as the precision
2366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * changes.
2367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
2368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code x.equals(new BigDecimal(x.toPlainString())} usually returns
2369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code false}.
2370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
2371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code x.compareTo(new BigDecimal(x.toPlainString())} returns {@code 0}.
23727cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
2373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a string representation of {@code this} without exponent part.
2374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String toPlainString() {
2376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String intStr = getUnscaledValue().toString();
2377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((scale == 0) || ((isZero()) && (scale < 0))) {
2378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return intStr;
2379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int begin = (signum() < 0) ? 1 : 0;
2381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int delta = scale;
2382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // We take space for all digits, plus a possible decimal point, plus 'scale'
23837f0c06f737b6f1f6b3a5bb30111f95dd0ca586a2Brian Carlstrom        StringBuilder result = new StringBuilder(intStr.length() + 1 + Math.abs(scale));
2384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (begin == 1) {
23867cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson            // If the number is negative, we insert a '-' character at front
2387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            result.append('-');
2388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (scale > 0) {
2390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            delta -= (intStr.length() - begin);
2391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (delta >= 0) {
23928454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes                result.append("0.");
2393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // To append zeros after the decimal point
2394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                for (; delta > CH_ZEROS.length; delta -= CH_ZEROS.length) {
2395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    result.append(CH_ZEROS);
2396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
2397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result.append(CH_ZEROS, 0, delta);
2398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result.append(intStr.substring(begin));
2399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else {
2400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                delta = begin - delta;
2401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result.append(intStr.substring(begin, delta));
2402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result.append('.');
2403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result.append(intStr.substring(delta));
2404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {// (scale <= 0)
2406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            result.append(intStr.substring(begin));
2407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // To append trailing zeros
2408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (; delta < -CH_ZEROS.length; delta += CH_ZEROS.length) {
2409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result.append(CH_ZEROS);
2410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            result.append(CH_ZEROS, 0, -delta);
2412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result.toString();
2414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns this {@code BigDecimal} as a big integer instance. A fractional
2418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * part is discarded.
24197cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
2420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return this {@code BigDecimal} as a big integer instance.
2421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigInteger toBigInteger() {
2423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((scale == 0) || (isZero())) {
2424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return getUnscaledValue();
2425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else if (scale < 0) {
2426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return getUnscaledValue().multiply(Multiplication.powerOf10(-(long)scale));
2427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {// (scale > 0)
2428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return getUnscaledValue().divide(Multiplication.powerOf10(scale));
2429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns this {@code BigDecimal} as a big integer instance if it has no
2434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * fractional part. If this {@code BigDecimal} has a fractional part, i.e.
2435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * if rounding would be necessary, an {@code ArithmeticException} is thrown.
24367cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
2437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return this {@code BigDecimal} as a big integer value.
2438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
2439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if rounding is necessary.
2440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigInteger toBigIntegerExact() {
2442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((scale == 0) || (isZero())) {
2443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return getUnscaledValue();
2444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else if (scale < 0) {
2445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return getUnscaledValue().multiply(Multiplication.powerOf10(-(long)scale));
2446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {// (scale > 0)
2447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            BigInteger[] integerAndFraction;
2448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // An optimization before do a heavy division
2449e866b788d613e0566b85b799fff998a09371520fJesse Wilson            if ((scale > approxPrecision()) || (scale > getUnscaledValue().getLowestSetBit())) {
24508454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes                throw new ArithmeticException("Rounding necessary");
2451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            integerAndFraction = getUnscaledValue().divideAndRemainder(Multiplication.powerOf10(scale));
2453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (integerAndFraction[1].signum() != 0) {
24547cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson                // It exists a non-zero fractional part
24558454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes                throw new ArithmeticException("Rounding necessary");
2456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return integerAndFraction[0];
2458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns this {@code BigDecimal} as an long value. Any fractional part is
2463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * discarded. If the integral part of {@code this} is too big to be
2464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * represented as an long, then {@code this} % 2^64 is returned.
24657cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
2466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return this {@code BigDecimal} as a long value.
2467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
2469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public long longValue() {
2470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /*
2471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * If scale <= -64 there are at least 64 trailing bits zero in
2472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * 10^(-scale). If the scale is positive and very large the long value
2473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * could be zero.
2474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
2475e866b788d613e0566b85b799fff998a09371520fJesse Wilson        return ((scale <= -64) || (scale > approxPrecision()) ? 0L
2476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                : toBigInteger().longValue());
2477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns this {@code BigDecimal} as a long value if it has no fractional
2481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * part and if its value fits to the int range ([-2^{63}..2^{63}-1]). If
2482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * these conditions are not met, an {@code ArithmeticException} is thrown.
24837cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
2484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return this {@code BigDecimal} as a long value.
2485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
2486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if rounding is necessary or the number doesn't fit in a long.
2487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public long longValueExact() {
2489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return valueExact(64);
2490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns this {@code BigDecimal} as an int value. Any fractional part is
2494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * discarded. If the integral part of {@code this} is too big to be
2495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * represented as an int, then {@code this} % 2^32 is returned.
24967cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
2497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return this {@code BigDecimal} as a int value.
2498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
2500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int intValue() {
2501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /*
2502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * If scale <= -32 there are at least 32 trailing bits zero in
2503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * 10^(-scale). If the scale is positive and very large the long value
2504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * could be zero.
2505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
2506e866b788d613e0566b85b799fff998a09371520fJesse Wilson        return ((scale <= -32) || (scale > approxPrecision())
2507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ? 0
2508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                : toBigInteger().intValue());
2509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns this {@code BigDecimal} as a int value if it has no fractional
2513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * part and if its value fits to the int range ([-2^{31}..2^{31}-1]). If
2514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * these conditions are not met, an {@code ArithmeticException} is thrown.
25157cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
2516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return this {@code BigDecimal} as a int value.
2517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
2518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if rounding is necessary or the number doesn't fit in a int.
2519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int intValueExact() {
2521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return (int)valueExact(32);
2522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns this {@code BigDecimal} as a short value if it has no fractional
2526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * part and if its value fits to the short range ([-2^{15}..2^{15}-1]). If
2527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * these conditions are not met, an {@code ArithmeticException} is thrown.
25287cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
2529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return this {@code BigDecimal} as a short value.
2530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
2531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if rounding is necessary of the number doesn't fit in a
2532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             short.
2533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public short shortValueExact() {
2535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return (short)valueExact(16);
2536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns this {@code BigDecimal} as a byte value if it has no fractional
2540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * part and if its value fits to the byte range ([-128..127]). If these
2541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * conditions are not met, an {@code ArithmeticException} is thrown.
25427cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
2543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return this {@code BigDecimal} as a byte value.
2544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException
2545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if rounding is necessary or the number doesn't fit in a byte.
2546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public byte byteValueExact() {
2548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return (byte)valueExact(8);
2549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns this {@code BigDecimal} as a float value. If {@code this} is too
2553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * big to be represented as an float, then {@code Float.POSITIVE_INFINITY}
2554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * or {@code Float.NEGATIVE_INFINITY} is returned.
2555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
2556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Note, that if the unscaled value has more than 24 significant digits,
2557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * then this decimal cannot be represented exactly in a float variable. In
2558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * this case the result is rounded.
2559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
2560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * For example, if the instance {@code x1 = new BigDecimal("0.1")} cannot be
2561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * represented exactly as a float, and thus {@code x1.equals(new
2562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * BigDecimal(x1.folatValue())} returns {@code false} for this case.
2563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
2564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Similarly, if the instance {@code new BigDecimal(16777217)} is converted
2565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * to a float, the result is {@code 1.6777216E}7.
25667cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
2567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return this {@code BigDecimal} as a float value.
2568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
2570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public float floatValue() {
2571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /* A similar code like in doubleValue() could be repeated here,
2572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * but this simple implementation is quite efficient. */
2573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        float floatResult = signum();
2574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long powerOfTwo = this.bitLength - (long)(scale / LOG10_2);
2575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((powerOfTwo < -149) || (floatResult == 0.0f)) {
2576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Cases which 'this' is very small
2577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            floatResult *= 0.0f;
2578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else if (powerOfTwo > 129) {
2579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Cases which 'this' is very large
2580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            floatResult *= Float.POSITIVE_INFINITY;
2581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
2582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            floatResult = (float)doubleValue();
2583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return floatResult;
2585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns this {@code BigDecimal} as a double value. If {@code this} is too
2589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * big to be represented as an float, then {@code Double.POSITIVE_INFINITY}
2590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * or {@code Double.NEGATIVE_INFINITY} is returned.
2591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
2592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Note, that if the unscaled value has more than 53 significant digits,
2593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * then this decimal cannot be represented exactly in a double variable. In
2594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * this case the result is rounded.
2595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
2596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * For example, if the instance {@code x1 = new BigDecimal("0.1")} cannot be
2597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * represented exactly as a double, and thus {@code x1.equals(new
2598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * BigDecimal(x1.doubleValue())} returns {@code false} for this case.
2599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
2600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Similarly, if the instance {@code new BigDecimal(9007199254740993L)} is
2601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * converted to a double, the result is {@code 9.007199254740992E15}.
2602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
26037cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
2604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return this {@code BigDecimal} as a double value.
2605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
2607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public double doubleValue() {
2608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int sign = signum();
2609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int exponent = 1076; // bias + 53
2610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int lowestSetBit;
2611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int discardedSize;
2612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long powerOfTwo = this.bitLength - (long)(scale / LOG10_2);
2613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long bits; // IEEE-754 Standard
26147cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson        long tempBits; // for temporal calculations
2615e866b788d613e0566b85b799fff998a09371520fJesse Wilson        BigInteger mantissa;
2616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((powerOfTwo < -1074) || (sign == 0)) {
26187cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson            // Cases which 'this' is very small
2619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return (sign * 0.0d);
2620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else if (powerOfTwo > 1025) {
26217cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson            // Cases which 'this' is very large
2622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return (sign * Double.POSITIVE_INFINITY);
2623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2624e866b788d613e0566b85b799fff998a09371520fJesse Wilson        mantissa = getUnscaledValue().abs();
2625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Let be:  this = [u,s], with s > 0
2626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (scale <= 0) {
2627e866b788d613e0566b85b799fff998a09371520fJesse Wilson            // mantissa = abs(u) * 10^s
2628e866b788d613e0566b85b799fff998a09371520fJesse Wilson            mantissa = mantissa.multiply(Multiplication.powerOf10(-scale));
2629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {// (scale > 0)
2630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            BigInteger quotAndRem[];
2631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            BigInteger powerOfTen = Multiplication.powerOf10(scale);
2632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int k = 100 - (int)powerOfTwo;
2633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int compRem;
2634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (k > 0) {
2636e866b788d613e0566b85b799fff998a09371520fJesse Wilson                /* Computing (mantissa * 2^k) , where 'k' is a enough big
2637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                 * power of '2' to can divide by 10^s */
2638e866b788d613e0566b85b799fff998a09371520fJesse Wilson                mantissa = mantissa.shiftLeft(k);
2639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                exponent -= k;
2640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2641e866b788d613e0566b85b799fff998a09371520fJesse Wilson            // Computing (mantissa * 2^k) / 10^s
2642e866b788d613e0566b85b799fff998a09371520fJesse Wilson            quotAndRem = mantissa.divideAndRemainder(powerOfTen);
2643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // To check if the fractional part >= 0.5
26447cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson            compRem = quotAndRem[1].shiftLeftOneBit().compareTo(powerOfTen);
2645e866b788d613e0566b85b799fff998a09371520fJesse Wilson            // To add two rounded bits at end of mantissa
2646e866b788d613e0566b85b799fff998a09371520fJesse Wilson            mantissa = quotAndRem[0].shiftLeft(2).add(
2647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    BigInteger.valueOf((compRem * (compRem + 3)) / 2 + 1));
2648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            exponent -= 2;
2649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2650e866b788d613e0566b85b799fff998a09371520fJesse Wilson        lowestSetBit = mantissa.getLowestSetBit();
2651e866b788d613e0566b85b799fff998a09371520fJesse Wilson        discardedSize = mantissa.bitLength() - 54;
2652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (discardedSize > 0) {// (n > 54)
2653e866b788d613e0566b85b799fff998a09371520fJesse Wilson            // mantissa = (abs(u) * 10^s) >> (n - 54)
2654e866b788d613e0566b85b799fff998a09371520fJesse Wilson            bits = mantissa.shiftRight(discardedSize).longValue();
2655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            tempBits = bits;
26567cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson            // #bits = 54, to check if the discarded fraction produces a carry
2657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if ((((bits & 1) == 1) && (lowestSetBit < discardedSize))
2658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    || ((bits & 3) == 3)) {
2659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                bits += 2;
2660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {// (n <= 54)
2662e866b788d613e0566b85b799fff998a09371520fJesse Wilson            // mantissa = (abs(u) * 10^s) << (54 - n)
2663e866b788d613e0566b85b799fff998a09371520fJesse Wilson            bits = mantissa.longValue() << -discardedSize;
2664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            tempBits = bits;
2665adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // #bits = 54, to check if the discarded fraction produces a carry:
2666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if ((bits & 3) == 3) {
2667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                bits += 2;
2668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Testing bit 54 to check if the carry creates a new binary digit
2671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((bits & 0x40000000000000L) == 0) {
2672e866b788d613e0566b85b799fff998a09371520fJesse Wilson            // To drop the last bit of mantissa (first discarded)
2673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            bits >>= 1;
2674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // exponent = 2^(s-n+53+bias)
2675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            exponent += discardedSize;
2676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {// #bits = 54
2677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            bits >>= 2;
2678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            exponent += discardedSize + 1;
2679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
26807cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson        // To test if the 53-bits number fits in 'double'
2681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (exponent > 2046) {// (exponent - bias > 1023)
2682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return (sign * Double.POSITIVE_INFINITY);
2683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else if (exponent <= 0) {// (exponent - bias <= -1023)
2684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Denormalized numbers (having exponent == 0)
2685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (exponent < -53) {// exponent - bias < -1076
2686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return (sign * 0.0d);
2687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
26887cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson            // -1076 <= exponent - bias <= -1023
2689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // To discard '- exponent + 1' bits
2690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            bits = tempBits >> 1;
2691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            tempBits = bits & (-1L >>> (63 + exponent));
2692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            bits >>= (-exponent );
2693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // To test if after discard bits, a new carry is generated
2694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (((bits & 3) == 3) || (((bits & 1) == 1) && (tempBits != 0)
2695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            && (lowestSetBit < discardedSize))) {
2696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                bits += 1;
2697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            exponent = 0;
2699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            bits >>= 1;
2700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2701e866b788d613e0566b85b799fff998a09371520fJesse Wilson        // Construct the 64 double bits: [sign(1), exponent(11), mantissa(52)]
2702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        bits = (sign & 0x8000000000000000L) | ((long)exponent << 52)
2703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                | (bits & 0xFFFFFFFFFFFFFL);
2704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return Double.longBitsToDouble(bits);
2705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the unit in the last place (ULP) of this {@code BigDecimal}
2709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * instance. An ULP is the distance to the nearest big decimal with the same
2710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * precision.
2711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
2712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The amount of a rounding error in the evaluation of a floating-point
2713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * operation is often expressed in ULPs. An error of 1 ULP is often seen as
2714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * a tolerable error.
2715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
2716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * For class {@code BigDecimal}, the ULP of a number is simply 10^(-scale).
2717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
2718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * For example, {@code new BigDecimal(0.1).ulp()} returns {@code 1E-55}.
27197cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
2720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return unit in the last place (ULP) of this {@code BigDecimal} instance.
2721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigDecimal ulp() {
2723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return valueOf(1, scale);
2724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /* Private Methods */
2727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * It does all rounding work of the public method
2730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code round(MathContext)}, performing an inplace rounding
2731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * without creating a new object.
27327cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
2733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param mc
2734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the {@code MathContext} for perform the rounding.
2735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #round(MathContext)
2736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void inplaceRound(MathContext mc) {
2738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int mcPrecision = mc.getPrecision();
2739e866b788d613e0566b85b799fff998a09371520fJesse Wilson        if (approxPrecision() < mcPrecision || mcPrecision == 0) {
2740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
2741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int discardedPrecision = precision() - mcPrecision;
2743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // If no rounding is necessary it returns immediately
2744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((discardedPrecision <= 0)) {
2745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
2746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // When the number is small perform an efficient rounding
2748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.bitLength < 64) {
2749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            smallRound(mc, discardedPrecision);
2750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
2751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Getting the integer part and the discarded fraction
2753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        BigInteger sizeOfFraction = Multiplication.powerOf10(discardedPrecision);
2754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        BigInteger[] integerAndFraction = getUnscaledValue().divideAndRemainder(sizeOfFraction);
2755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long newScale = (long)scale - discardedPrecision;
2756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int compRem;
2757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        BigDecimal tempBD;
2758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // If the discarded fraction is non-zero, perform rounding
2759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (integerAndFraction[1].signum() != 0) {
2760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // To check if the discarded fraction >= 0.5
27617cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson            compRem = (integerAndFraction[1].abs().shiftLeftOneBit().compareTo(sizeOfFraction));
2762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // To look if there is a carry
2763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            compRem =  roundingBehavior( integerAndFraction[0].testBit(0) ? 1 : 0,
2764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    integerAndFraction[1].signum() * (5 + compRem),
2765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    mc.getRoundingMode());
2766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (compRem != 0) {
2767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                integerAndFraction[0] = integerAndFraction[0].add(BigInteger.valueOf(compRem));
2768adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2769adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            tempBD = new BigDecimal(integerAndFraction[0]);
2770adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // If after to add the increment the precision changed, we normalize the size
2771adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (tempBD.precision() > mcPrecision) {
2772adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                integerAndFraction[0] = integerAndFraction[0].divide(BigInteger.TEN);
2773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                newScale--;
2774adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // To update all internal fields
27772850a53dfbd0c172aedaec3493aad572a5ec023dJesse Wilson        scale = safeLongToInt(newScale);
2778adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        precision = mcPrecision;
2779adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        setUnscaledValue(integerAndFraction[0]);
2780adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2781adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2782adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static int longCompareTo(long value1, long value2) {
2783adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return value1 > value2 ? 1 : (value1 < value2 ? -1 : 0);
2784adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2785adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2786adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * This method implements an efficient rounding for numbers which unscaled
2787adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * value fits in the type {@code long}.
27887cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
2789adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param mc
2790adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the context to use
2791adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param discardedPrecision
2792adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the number of decimal digits that are discarded
2793adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #round(MathContext)
2794adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2795adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void smallRound(MathContext mc, int discardedPrecision) {
2796706de1164836051ab31cc69eb77a6bba1a723896Elliott Hughes        long sizeOfFraction = MathUtils.LONG_POWERS_OF_TEN[discardedPrecision];
2797adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long newScale = (long)scale - discardedPrecision;
2798adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long unscaledVal = smallValue;
2799adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Getting the integer part and the discarded fraction
2800adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long integer = unscaledVal / sizeOfFraction;
2801adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long fraction = unscaledVal % sizeOfFraction;
2802adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int compRem;
2803adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // If the discarded fraction is non-zero perform rounding
2804adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (fraction != 0) {
2805adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // To check if the discarded fraction >= 0.5
2806b5bde2fd72189192b52e726a2d606d70c3c8a34bElliott Hughes            compRem = longCompareTo(Math.abs(fraction) * 2, sizeOfFraction);
2807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // To look if there is a carry
2808adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            integer += roundingBehavior( ((int)integer) & 1,
2809adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    Long.signum(fraction) * (5 + compRem),
2810adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    mc.getRoundingMode());
2811adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // If after to add the increment the precision changed, we normalize the size
2812adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (Math.log10(Math.abs(integer)) >= mc.getPrecision()) {
2813adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                integer /= 10;
2814adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                newScale--;
2815adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2816adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2817adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // To update all internal fields
28182850a53dfbd0c172aedaec3493aad572a5ec023dJesse Wilson        scale = safeLongToInt(newScale);
2819adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        precision = mc.getPrecision();
2820adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        smallValue = integer;
2821adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        bitLength = bitLength(integer);
2822adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        intVal = null;
2823adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2824adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2825adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Return an increment that can be -1,0 or 1, depending of
2827adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code roundingMode}.
28287cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
2829adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param parityBit
2830adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            can be 0 or 1, it's only used in the case
2831adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            {@code HALF_EVEN}
2832adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param fraction
2833e866b788d613e0566b85b799fff998a09371520fJesse Wilson     *            the mantissa to be analyzed
2834adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param roundingMode
2835adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the type of rounding
2836adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the carry propagated after rounding
2837adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2838adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static int roundingBehavior(int parityBit, int fraction, RoundingMode roundingMode) {
2839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int increment = 0; // the carry after rounding
2840adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2841adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        switch (roundingMode) {
2842adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case UNNECESSARY:
2843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (fraction != 0) {
28448454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes                    throw new ArithmeticException("Rounding necessary");
2845adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
2846adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
2847adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case UP:
2848adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                increment = Integer.signum(fraction);
2849adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
2850adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case DOWN:
2851adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
2852adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case CEILING:
2853adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                increment = Math.max(Integer.signum(fraction), 0);
2854adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
2855adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case FLOOR:
2856adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                increment = Math.min(Integer.signum(fraction), 0);
2857adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
2858adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case HALF_UP:
2859adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (Math.abs(fraction) >= 5) {
2860adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    increment = Integer.signum(fraction);
2861adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
2862adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
2863adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case HALF_DOWN:
2864adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (Math.abs(fraction) > 5) {
2865adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    increment = Integer.signum(fraction);
2866adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
2867adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
2868adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case HALF_EVEN:
2869adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (Math.abs(fraction) + parityBit > 5) {
2870adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    increment = Integer.signum(fraction);
2871adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
2872adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
2873adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2874adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return increment;
2875adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2876adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2877adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2878adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * If {@code intVal} has a fractional part throws an exception,
2879adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * otherwise it counts the number of bits of value and checks if it's out of
2880adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the range of the primitive type. If the number fits in the primitive type
2881adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * returns this number as {@code long}, otherwise throws an
2882adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * exception.
28837cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
2884adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param bitLengthOfType
2885adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            number of bits of the type whose value will be calculated
2886adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            exactly
2887adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the exact value of the integer part of {@code BigDecimal}
2888adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         when is possible
2889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArithmeticException when rounding is necessary or the
2890adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             number don't fit in the primitive type
2891adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2892adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private long valueExact(int bitLengthOfType) {
2893adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        BigInteger bigInteger = toBigIntegerExact();
2894adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2895adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (bigInteger.bitLength() < bitLengthOfType) {
2896adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // It fits in the primitive type
2897adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return bigInteger.longValue();
2898adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
28998454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes        throw new ArithmeticException("Rounding necessary");
2900adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2901adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2902adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2903adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * If the precision already was calculated it returns that value, otherwise
2904adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * it calculates a very good approximation efficiently . Note that this
2905adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * value will be {@code precision()} or {@code precision()-1}
2906adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * in the worst case.
29077cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
2908adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return an approximation of {@code precision()} value
2909adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2910e866b788d613e0566b85b799fff998a09371520fJesse Wilson    private int approxPrecision() {
2911adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return precision > 0
2912adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                ? precision
2913adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                : (int) ((this.bitLength - 1) * LOG10_2) + 1;
2914adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2915adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
29162850a53dfbd0c172aedaec3493aad572a5ec023dJesse Wilson    private static int safeLongToInt(long longValue) {
29172850a53dfbd0c172aedaec3493aad572a5ec023dJesse Wilson        if (longValue < Integer.MIN_VALUE || longValue > Integer.MAX_VALUE) {
29182850a53dfbd0c172aedaec3493aad572a5ec023dJesse Wilson            throw new ArithmeticException("Out of int range: " + longValue);
2919adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
29202850a53dfbd0c172aedaec3493aad572a5ec023dJesse Wilson        return (int) longValue;
2921adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2922adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2923adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2924adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * It returns the value 0 with the most approximated scale of type
2925adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code int}. if {@code longScale > Integer.MAX_VALUE} the
2926adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * scale will be {@code Integer.MAX_VALUE}; if
2927adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code longScale < Integer.MIN_VALUE} the scale will be
2928adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code Integer.MIN_VALUE}; otherwise {@code longScale} is
2929adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * casted to the type {@code int}.
29307cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson     *
2931adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param longScale
2932adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the scale to which the value 0 will be scaled.
2933adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the value 0 scaled by the closer scale of type {@code int}.
2934adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #scale
2935adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2936adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static BigDecimal zeroScaledBy(long longScale) {
2937adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (longScale == (int) longScale) {
2938adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return valueOf(0,(int)longScale);
2939adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2940adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (longScale >= 0) {
2941adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return new BigDecimal( 0, Integer.MAX_VALUE);
2942adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2943adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return new BigDecimal( 0, Integer.MIN_VALUE);
2944adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2945adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2946adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2947e866b788d613e0566b85b799fff998a09371520fJesse Wilson     * Assigns all transient fields upon deserialization of a
2948adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code BigDecimal} instance (bitLength and smallValue). The transient
2949adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * field precision is assigned lazily.
2950adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2951adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void readObject(ObjectInputStream in) throws IOException,
2952adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ClassNotFoundException {
2953adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        in.defaultReadObject();
2954adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2955adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.bitLength = intVal.bitLength();
2956adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.bitLength < 64) {
2957adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.smallValue = intVal.longValue();
2958adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2959adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2960adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2961adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2962adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Prepares this {@code BigDecimal} for serialization, i.e. the
2963adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * non-transient field {@code intVal} is assigned.
2964adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2965adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void writeObject(ObjectOutputStream out) throws IOException {
2966adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        getUnscaledValue();
2967adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        out.defaultWriteObject();
2968adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2969adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2970adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private BigInteger getUnscaledValue() {
2971adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if(intVal == null) {
2972adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            intVal = BigInteger.valueOf(smallValue);
2973adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2974adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return intVal;
2975adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
29767cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson
2977adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void setUnscaledValue(BigInteger unscaledValue) {
2978adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.intVal = unscaledValue;
2979adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.bitLength = unscaledValue.bitLength();
2980adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if(this.bitLength < 64) {
2981adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.smallValue = unscaledValue.longValue();
2982adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2983adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
29847cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson
2985adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static int bitLength(long smallValue) {
2986adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if(smallValue < 0) {
2987adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            smallValue = ~smallValue;
2988adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2989adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return 64 - Long.numberOfLeadingZeros(smallValue);
2990adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
29917cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson
2992adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static int bitLength(int smallValue) {
2993adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if(smallValue < 0) {
2994adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            smallValue = ~smallValue;
2995adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2996adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return 32 - Integer.numberOfLeadingZeros(smallValue);
2997adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
29987cf86eabacd844cae438db573d45727d7b3374bfJesse Wilson
2999adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
3000