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