0001: /*
0002: * Licensed to the Apache Software Foundation (ASF) under one or more
0003: * contributor license agreements. See the NOTICE file distributed with
0004: * this work for additional information regarding copyright ownership.
0005: * The ASF licenses this file to You under the Apache License, Version 2.0
0006: * (the "License"); you may not use this file except in compliance with
0007: * the License. You may obtain a copy of the License at
0008: *
0009: * http://www.apache.org/licenses/LICENSE-2.0
0010: *
0011: * Unless required by applicable law or agreed to in writing, software
0012: * distributed under the License is distributed on an "AS IS" BASIS,
0013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014: * See the License for the specific language governing permissions and
0015: * limitations under the License.
0016: */
0017:
0018: package java.math;
0019:
0020: import java.io.IOException;
0021: import java.io.ObjectInputStream;
0022: import java.io.ObjectOutputStream;
0023: import java.io.Serializable;
0024:
0025: import org.apache.harmony.math.internal.nls.Messages;
0026:
0027: /**
0028: * @author Intel Middleware Product Division
0029: * @author Instituto Tecnologico de Cordoba
0030: */
0031: public class BigDecimal extends Number implements
0032: Comparable<BigDecimal>, Serializable {
0033: /* Static Fields */
0034:
0035: /** @ar.org.fitc.spec_ref */
0036: public static final BigDecimal ZERO = new BigDecimal(0, 0);
0037:
0038: /** @ar.org.fitc.spec_ref */
0039: public static final BigDecimal ONE = new BigDecimal(1, 0);
0040:
0041: /** @ar.org.fitc.spec_ref */
0042: public static final BigDecimal TEN = new BigDecimal(10, 0);
0043:
0044: /** @ar.org.fitc.spec_ref */
0045: public static final int ROUND_UP = 0;
0046:
0047: /** @ar.org.fitc.spec_ref */
0048: public static final int ROUND_DOWN = 1;
0049:
0050: /** @ar.org.fitc.spec_ref */
0051: public static final int ROUND_CEILING = 2;
0052:
0053: /** @ar.org.fitc.spec_ref */
0054: public static final int ROUND_FLOOR = 3;
0055:
0056: /** @ar.org.fitc.spec_ref */
0057: public static final int ROUND_HALF_UP = 4;
0058:
0059: /** @ar.org.fitc.spec_ref */
0060: public static final int ROUND_HALF_DOWN = 5;
0061:
0062: /** @ar.org.fitc.spec_ref */
0063: public static final int ROUND_HALF_EVEN = 6;
0064:
0065: /** @ar.org.fitc.spec_ref */
0066: public static final int ROUND_UNNECESSARY = 7;
0067:
0068: /* Private Fields */
0069:
0070: /** @ar.org.fitc.spec_ref */
0071: private static final long serialVersionUID = 6108874887143696463L;
0072:
0073: /** The double closer to <code>Log10(2)</code>. */
0074: private static final double LOG10_2 = 0.3010299956639812;
0075:
0076: /** The <code>String</code> representation is cached. */
0077: private transient String toStringImage = null;
0078:
0079: private transient int hashCode = 0;
0080:
0081: /**
0082: * An array with powers of five that fit in the type <code>long</code>
0083: * (<code>5^0,5^1,...,5^27</code>)
0084: */
0085: private static final BigInteger FIVE_POW[];
0086:
0087: /**
0088: * An array with powers of ten that fit in the type <code>long</code>
0089: * (<code>10^0,10^1,...,10^18</code>)
0090: */
0091: private static final BigInteger TEN_POW[];
0092:
0093: /**
0094: * An array with powers of ten that fit in the type <code>long</code>
0095: * (<code>10^0,10^1,...,10^18</code>)
0096: */
0097: private static final long[] LONG_TEN_POW = new long[] { 1L, 10L,
0098: 100L, 1000L, 10000L, 100000L, 1000000L, 10000000L,
0099: 100000000L, 1000000000L, 10000000000L, 100000000000L,
0100: 1000000000000L, 10000000000000L, 100000000000000L,
0101: 1000000000000000L, 10000000000000000L, 100000000000000000L,
0102: 1000000000000000000L, };
0103:
0104: private static final long[] LONG_FIVE_POW = new long[] { 1L, 5L,
0105: 25L, 125L, 625L, 3125L, 15625L, 78125L, 390625L, 1953125L,
0106: 9765625L, 48828125L, 244140625L, 1220703125L, 6103515625L,
0107: 30517578125L, 152587890625L, 762939453125L, 3814697265625L,
0108: 19073486328125L, 95367431640625L, 476837158203125L,
0109: 2384185791015625L, 11920928955078125L, 59604644775390625L,
0110: 298023223876953125L, 1490116119384765625L,
0111: 7450580596923828125L, };
0112:
0113: private static final int[] LONG_FIVE_POW_BIT_LENGTH = new int[LONG_FIVE_POW.length];
0114: private static final int[] LONG_TEN_POW_BIT_LENGTH = new int[LONG_TEN_POW.length];
0115:
0116: private static final int BI_SCALED_BY_ZERO_LENGTH = 11;
0117: /**
0118: * An array with the first <code>BigInteger</code> scaled by zero.
0119: * (<code>[0,0],[1,0],...,[10,0]</code>)
0120: */
0121: private static final BigDecimal BI_SCALED_BY_ZERO[] = new BigDecimal[BI_SCALED_BY_ZERO_LENGTH];
0122:
0123: /**
0124: * An array with the zero number scaled by the first positive scales.
0125: * (<code>0*10^0, 0*10^1, ..., 0*10^10</code>)
0126: */
0127: private static final BigDecimal ZERO_SCALED_BY[] = new BigDecimal[11];
0128:
0129: /** An array filled with characters <code>'0'</code>. */
0130: private static final char[] CH_ZEROS = new char[100];
0131:
0132: static {
0133: // To fill all static arrays.
0134: int i = 0;
0135:
0136: for (; i < ZERO_SCALED_BY.length; i++) {
0137: BI_SCALED_BY_ZERO[i] = new BigDecimal(i, 0);
0138: ZERO_SCALED_BY[i] = new BigDecimal(0, i);
0139: CH_ZEROS[i] = '0';
0140: }
0141:
0142: for (; i < CH_ZEROS.length; i++) {
0143: CH_ZEROS[i] = '0';
0144: }
0145: for (int j = 0; j < LONG_FIVE_POW_BIT_LENGTH.length; j++) {
0146: LONG_FIVE_POW_BIT_LENGTH[j] = bitLength(LONG_FIVE_POW[j]);
0147: }
0148: for (int j = 0; j < LONG_TEN_POW_BIT_LENGTH.length; j++) {
0149: LONG_TEN_POW_BIT_LENGTH[j] = bitLength(LONG_TEN_POW[j]);
0150: }
0151:
0152: // Taking the references of useful powers.
0153: TEN_POW = Multiplication.bigTenPows;
0154: FIVE_POW = Multiplication.bigFivePows;
0155: }
0156:
0157: /**
0158: * The arbitrary precision integer (unscaled value) in the internal
0159: * representation of <code>BigDecimal</code>.
0160: */
0161: private BigInteger intVal;
0162:
0163: private transient int bitLength;
0164:
0165: private transient long smallValue;
0166:
0167: /**
0168: * The 32-bit integer scale in the internal representation of <code>BigDecimal</code>.
0169: */
0170: private int scale;
0171:
0172: /**
0173: * Represent the number of decimal digits in the unscaled value. This
0174: * precision is calculated the first time, and used in the following
0175: * calls of method <code>precision()</code>. Note that some call to
0176: * the private method <code>inplaceRound()</code> could update this field.
0177: * @see #precision()
0178: * @see #inplaceRound(MathContext)
0179: */
0180: private transient int precision = 0;
0181:
0182: /* Constructors */
0183:
0184: private BigDecimal(long smallValue, int scale) {
0185: this .smallValue = smallValue;
0186: this .scale = scale;
0187: this .bitLength = bitLength(smallValue);
0188: }
0189:
0190: private BigDecimal(int smallValue, int scale) {
0191: this .smallValue = smallValue;
0192: this .scale = scale;
0193: this .bitLength = bitLength(smallValue);
0194: }
0195:
0196: /** @ar.org.fitc.spec_ref */
0197: public BigDecimal(char[] in, int offset, int len) {
0198: int begin = offset; // first index to be copied
0199: int last = offset + (len - 1); // last index to be copied
0200: String scaleString = null; // buffer for scale
0201: StringBuilder unscaledBuffer; // buffer for unscaled value
0202: long newScale; // the new scale
0203:
0204: if (in == null) {
0205: throw new NullPointerException();
0206: }
0207: if ((last >= in.length) || (offset < 0) || (len <= 0)
0208: || (last < 0)) {
0209: throw new NumberFormatException();
0210: }
0211: unscaledBuffer = new StringBuilder(len);
0212: int bufLength = 0;
0213: // To skip a possible '+' symbol
0214: if ((offset <= last) && (in[offset] == '+')) {
0215: offset++;
0216: begin++;
0217: }
0218: int counter = 0;
0219: boolean wasNonZero = false;
0220: // Accumulating all digits until a possible decimal point
0221: for (; (offset <= last) && (in[offset] != '.')
0222: && (in[offset] != 'e') && (in[offset] != 'E'); offset++) {
0223: if (!wasNonZero) {
0224: if (in[offset] == '0') {
0225: counter++;
0226: } else {
0227: wasNonZero = true;
0228: }
0229: }
0230: ;
0231:
0232: }
0233: unscaledBuffer.append(in, begin, offset - begin);
0234: bufLength += offset - begin;
0235: // A decimal point was found
0236: if ((offset <= last) && (in[offset] == '.')) {
0237: offset++;
0238: // Accumulating all digits until a possible exponent
0239: begin = offset;
0240: for (; (offset <= last) && (in[offset] != 'e')
0241: && (in[offset] != 'E'); offset++) {
0242: if (!wasNonZero) {
0243: if (in[offset] == '0') {
0244: counter++;
0245: } else {
0246: wasNonZero = true;
0247: }
0248: }
0249: ;
0250: }
0251: scale = offset - begin;
0252: bufLength += scale;
0253: unscaledBuffer.append(in, begin, scale);
0254: } else {
0255: scale = 0;
0256: }
0257: // An exponent was found
0258: if ((offset <= last)
0259: && ((in[offset] == 'e') || (in[offset] == 'E'))) {
0260: offset++;
0261: // Checking for a possible sign of scale
0262: begin = offset;
0263: if ((offset <= last) && (in[offset] == '+')) {
0264: offset++;
0265: if ((offset <= last) && (in[offset] != '-')) {
0266: begin++;
0267: }
0268: }
0269: // Accumulating all remaining digits
0270: scaleString = String.valueOf(in, begin, last + 1 - begin);
0271: // Checking if the scale is defined
0272: newScale = (long) scale - Integer.parseInt(scaleString);
0273: scale = (int) newScale;
0274: if (newScale != scale) {
0275: // math.02=Scale out of range.
0276: throw new NumberFormatException(Messages
0277: .getString("math.02")); //$NON-NLS-1$
0278: }
0279: }
0280: // Parsing the unscaled value
0281: if (bufLength < 19) {
0282: smallValue = Long.parseLong(unscaledBuffer.toString());
0283: bitLength = bitLength(smallValue);
0284: } else {
0285: setUnscaledValue(new BigInteger(unscaledBuffer.toString()));
0286: }
0287: precision = unscaledBuffer.length() - counter;
0288: if (unscaledBuffer.charAt(0) == '-') {
0289: precision--;
0290: }
0291: }
0292:
0293: /** @ar.org.fitc.spec_ref */
0294: public BigDecimal(char[] in, int offset, int len, MathContext mc) {
0295: this (in, offset, len);
0296: inplaceRound(mc);
0297: }
0298:
0299: /** @ar.org.fitc.spec_ref */
0300: public BigDecimal(char[] in) {
0301: this (in, 0, in.length);
0302: }
0303:
0304: /** @ar.org.fitc.spec_ref */
0305: public BigDecimal(char[] in, MathContext mc) {
0306: this (in, 0, in.length);
0307: inplaceRound(mc);
0308: }
0309:
0310: /** @ar.org.fitc.spec_ref */
0311: public BigDecimal(String val) {
0312: this (val.toCharArray(), 0, val.length());
0313: }
0314:
0315: /** @ar.org.fitc.spec_ref */
0316: public BigDecimal(String val, MathContext mc) {
0317: this (val.toCharArray(), 0, val.length());
0318: inplaceRound(mc);
0319: }
0320:
0321: /** @ar.org.fitc.spec_ref */
0322: public BigDecimal(double val) {
0323: if (Double.isInfinite(val) || Double.isNaN(val)) {
0324: // math.03=Infinity or NaN
0325: throw new NumberFormatException(Messages
0326: .getString("math.03")); //$NON-NLS-1$
0327: }
0328: long bits = Double.doubleToLongBits(val); // IEEE-754
0329: long mantisa;
0330: int trailingZeros;
0331: // Extracting the exponent, note that the bias is 1023
0332: scale = 1075 - (int) ((bits >> 52) & 0x7FFL);
0333: // Extracting the 52 bits of the mantisa.
0334: mantisa = (scale == 1075) ? (bits & 0xFFFFFFFFFFFFFL) << 1
0335: : (bits & 0xFFFFFFFFFFFFFL) | 0x10000000000000L;
0336: if (mantisa == 0) {
0337: scale = 0;
0338: precision = 1;
0339: }
0340: // To simplify all factors '2' in the mantisa
0341: if (scale > 0) {
0342: trailingZeros = Math.min(scale, Long
0343: .numberOfTrailingZeros(mantisa));
0344: mantisa >>>= trailingZeros;
0345: scale -= trailingZeros;
0346: }
0347: // Calculating the new unscaled value and the new scale
0348: if ((bits >> 63) != 0) {
0349: mantisa = -mantisa;
0350: }
0351: int mantisaBits = bitLength(mantisa);
0352: if (scale < 0) {
0353: bitLength = mantisaBits == 0 ? 0 : mantisaBits - scale;
0354: if (bitLength < 64) {
0355: smallValue = mantisa << (-scale);
0356: } else {
0357: intVal = BigInteger.valueOf(mantisa).shiftLeft(-scale);
0358: }
0359: scale = 0;
0360: } else if (scale > 0) {
0361: // m * 2^e = (m * 5^(-e)) * 10^e
0362: if (scale < LONG_FIVE_POW.length
0363: && mantisaBits + LONG_FIVE_POW_BIT_LENGTH[scale] < 64) {
0364: smallValue = mantisa * LONG_FIVE_POW[scale];
0365: bitLength = bitLength(smallValue);
0366: } else {
0367: setUnscaledValue(Multiplication.multiplyByFivePow(
0368: BigInteger.valueOf(mantisa), scale));
0369: }
0370: } else { // scale == 0
0371: smallValue = mantisa;
0372: bitLength = mantisaBits;
0373: }
0374: }
0375:
0376: /** @ar.org.fitc.spec_ref */
0377: public BigDecimal(double val, MathContext mc) {
0378: this (val);
0379: inplaceRound(mc);
0380: }
0381:
0382: /** @ar.org.fitc.spec_ref */
0383: public BigDecimal(BigInteger val) {
0384: this (val, 0);
0385: }
0386:
0387: /** @ar.org.fitc.spec_ref */
0388: public BigDecimal(BigInteger val, MathContext mc) {
0389: this (val);
0390: inplaceRound(mc);
0391: }
0392:
0393: /** @ar.org.fitc.spec_ref */
0394: public BigDecimal(BigInteger unscaledVal, int scale) {
0395: if (unscaledVal == null) {
0396: throw new NullPointerException();
0397: }
0398: this .scale = scale;
0399: setUnscaledValue(unscaledVal);
0400: }
0401:
0402: /** @ar.org.fitc.spec_ref */
0403: public BigDecimal(BigInteger unscaledVal, int scale, MathContext mc) {
0404: this (unscaledVal, scale);
0405: inplaceRound(mc);
0406: }
0407:
0408: /** @ar.org.fitc.spec_ref */
0409: public BigDecimal(int val) {
0410: this (val, 0);
0411: }
0412:
0413: /** @ar.org.fitc.spec_ref */
0414: public BigDecimal(int val, MathContext mc) {
0415: this (val, 0);
0416: inplaceRound(mc);
0417: }
0418:
0419: /** @ar.org.fitc.spec_ref */
0420: public BigDecimal(long val) {
0421: this (val, 0);
0422: }
0423:
0424: /** @ar.org.fitc.spec_ref */
0425: public BigDecimal(long val, MathContext mc) {
0426: this (val);
0427: inplaceRound(mc);
0428: }
0429:
0430: /* Public Methods */
0431:
0432: /** @ar.org.fitc.spec_ref */
0433: public static BigDecimal valueOf(long unscaledVal, int scale) {
0434: if (scale == 0) {
0435: return valueOf(unscaledVal);
0436: }
0437: if ((unscaledVal == 0) && (scale >= 0)
0438: && (scale < ZERO_SCALED_BY.length)) {
0439: return ZERO_SCALED_BY[scale];
0440: }
0441: return new BigDecimal(unscaledVal, scale);
0442: }
0443:
0444: /** @ar.org.fitc.spec_ref */
0445: public static BigDecimal valueOf(long unscaledVal) {
0446: if ((unscaledVal >= 0)
0447: && (unscaledVal < BI_SCALED_BY_ZERO_LENGTH)) {
0448: return BI_SCALED_BY_ZERO[(int) unscaledVal];
0449: }
0450: return new BigDecimal(unscaledVal, 0);
0451: }
0452:
0453: /** @ar.org.fitc.spec_ref */
0454: public static BigDecimal valueOf(double val) {
0455: if (Double.isInfinite(val) || Double.isNaN(val)) {
0456: // math.03=Infinity or NaN
0457: throw new NumberFormatException(Messages
0458: .getString("math.03")); //$NON-NLS-1$
0459: }
0460: return new BigDecimal(Double.toString(val));
0461: }
0462:
0463: /** @ar.org.fitc.spec_ref */
0464: public BigDecimal add(BigDecimal augend) {
0465: int diffScale = this .scale - augend.scale;
0466: // Fast return when some operand is zero
0467: if (this .isZero()) {
0468: if (diffScale <= 0) {
0469: return augend;
0470: }
0471: if (augend.isZero()) {
0472: return this ;
0473: }
0474: } else if (augend.isZero()) {
0475: if (diffScale >= 0) {
0476: return this ;
0477: }
0478: }
0479: // Let be: this = [u1,s1] and augend = [u2,s2]
0480: if (diffScale == 0) {
0481: // case s1 == s2: [u1 + u2 , s1]
0482: if (Math.max(this .bitLength, augend.bitLength) + 1 < 64) {
0483: return valueOf(this .smallValue + augend.smallValue,
0484: this .scale);
0485: }
0486: return new BigDecimal(this .getUnscaledValue().add(
0487: augend.getUnscaledValue()), this .scale);
0488: } else if (diffScale > 0) {
0489: // case s1 > s2 : [(u1 + u2) * 10 ^ (s1 - s2) , s1]
0490: return addAndMult10(this , augend, diffScale);
0491: } else {// case s2 > s1 : [(u2 + u1) * 10 ^ (s2 - s1) , s2]
0492: return addAndMult10(augend, this , -diffScale);
0493: }
0494: }
0495:
0496: private static BigDecimal addAndMult10(BigDecimal this Value,
0497: BigDecimal augend, int diffScale) {
0498: if (diffScale < LONG_TEN_POW.length
0499: && Math.max(this Value.bitLength, augend.bitLength
0500: + LONG_TEN_POW_BIT_LENGTH[diffScale]) + 1 < 64) {
0501: return valueOf(this Value.smallValue + augend.smallValue
0502: * LONG_TEN_POW[diffScale], this Value.scale);
0503: }
0504: return new BigDecimal(this Value.getUnscaledValue().add(
0505: Multiplication.multiplyByTenPow(augend
0506: .getUnscaledValue(), diffScale)),
0507: this Value.scale);
0508: }
0509:
0510: /** @ar.org.fitc.spec_ref */
0511: public BigDecimal add(BigDecimal augend, MathContext mc) {
0512: BigDecimal larger; // operand with the largest unscaled value
0513: BigDecimal smaller; // operand with the smallest unscaled value
0514: BigInteger tempBI;
0515: long diffScale = (long) this .scale - augend.scale;
0516: int largerSignum;
0517: // Some operand is zero or the precision is infinity
0518: if ((augend.isZero()) || (this .isZero())
0519: || (mc.getPrecision() == 0)) {
0520: return add(augend).round(mc);
0521: }
0522: // Cases where there is room for optimizations
0523: if (this .aproxPrecision() < diffScale - 1) {
0524: larger = augend;
0525: smaller = this ;
0526: } else if (augend.aproxPrecision() < -diffScale - 1) {
0527: larger = this ;
0528: smaller = augend;
0529: } else {// No optimization is done
0530: return add(augend).round(mc);
0531: }
0532: if (mc.getPrecision() >= larger.aproxPrecision()) {
0533: // No optimization is done
0534: return add(augend).round(mc);
0535: }
0536: // Cases where it's unnecessary to add two numbers with very different scales
0537: largerSignum = larger.signum();
0538: if (largerSignum == smaller.signum()) {
0539: tempBI = Multiplication.multiplyByPositiveInt(
0540: larger.getUnscaledValue(), 10).add(
0541: BigInteger.valueOf(largerSignum));
0542: } else {
0543: tempBI = larger.getUnscaledValue().subtract(
0544: BigInteger.valueOf(largerSignum));
0545: tempBI = Multiplication.multiplyByPositiveInt(tempBI, 10)
0546: .add(BigInteger.valueOf(largerSignum * 9));
0547: }
0548: // Rounding the improved adding
0549: larger = new BigDecimal(tempBI, larger.scale + 1);
0550: return larger.round(mc);
0551: }
0552:
0553: /** @ar.org.fitc.spec_ref */
0554: public BigDecimal subtract(BigDecimal subtrahend) {
0555: int diffScale = this .scale - subtrahend.scale;
0556: // Fast return when some operand is zero
0557: if (this .isZero()) {
0558: if (diffScale <= 0) {
0559: return subtrahend.negate();
0560: }
0561: if (subtrahend.isZero()) {
0562: return this ;
0563: }
0564: } else if (subtrahend.isZero()) {
0565: if (diffScale >= 0) {
0566: return this ;
0567: }
0568: }
0569: // Let be: this = [u1,s1] and subtrahend = [u2,s2] so:
0570: if (diffScale == 0) {
0571: // case s1 = s2 : [u1 - u2 , s1]
0572: if (Math.max(this .bitLength, subtrahend.bitLength) + 1 < 64) {
0573: return valueOf(this .smallValue - subtrahend.smallValue,
0574: this .scale);
0575: }
0576: return new BigDecimal(this .getUnscaledValue().subtract(
0577: subtrahend.getUnscaledValue()), this .scale);
0578: } else if (diffScale > 0) {
0579: // case s1 > s2 : [ u1 - u2 * 10 ^ (s1 - s2) , s1 ]
0580: if (diffScale < LONG_TEN_POW.length
0581: && Math.max(this .bitLength, subtrahend.bitLength
0582: + LONG_TEN_POW_BIT_LENGTH[diffScale]) + 1 < 64) {
0583: return valueOf(this .smallValue - subtrahend.smallValue
0584: * LONG_TEN_POW[diffScale], this .scale);
0585: }
0586: return new BigDecimal(this .getUnscaledValue().subtract(
0587: Multiplication.multiplyByTenPow(subtrahend
0588: .getUnscaledValue(), diffScale)),
0589: this .scale);
0590: } else {// case s2 > s1 : [ u1 * 10 ^ (s2 - s1) - u2 , s2 ]
0591: diffScale = -diffScale;
0592: if (diffScale < LONG_TEN_POW.length
0593: && Math.max(this .bitLength
0594: + LONG_TEN_POW_BIT_LENGTH[diffScale],
0595: subtrahend.bitLength) + 1 < 64) {
0596: return valueOf(this .smallValue
0597: * LONG_TEN_POW[diffScale]
0598: - subtrahend.smallValue, subtrahend.scale);
0599: }
0600: return new BigDecimal(Multiplication.multiplyByTenPow(
0601: this .getUnscaledValue(), diffScale).subtract(
0602: subtrahend.getUnscaledValue()), subtrahend.scale);
0603: }
0604: }
0605:
0606: /** @ar.org.fitc.spec_ref */
0607: public BigDecimal subtract(BigDecimal subtrahend, MathContext mc) {
0608: long diffScale = subtrahend.scale - (long) this .scale;
0609: int this Signum;
0610: BigDecimal leftOperand; // it will be only the left operand (this)
0611: BigInteger tempBI;
0612: // Some operand is zero or the precision is infinity
0613: if ((subtrahend.isZero()) || (this .isZero())
0614: || (mc.getPrecision() == 0)) {
0615: return subtract(subtrahend).round(mc);
0616: }
0617: // Now: this != 0 and subtrahend != 0
0618: if (subtrahend.aproxPrecision() < diffScale - 1) {
0619: // Cases where it is unnecessary to subtract two numbers with very different scales
0620: if (mc.getPrecision() < this .aproxPrecision()) {
0621: this Signum = this .signum();
0622: if (this Signum != subtrahend.signum()) {
0623: tempBI = Multiplication.multiplyByPositiveInt(
0624: this .getUnscaledValue(), 10).add(
0625: BigInteger.valueOf(this Signum));
0626: } else {
0627: tempBI = this .getUnscaledValue().subtract(
0628: BigInteger.valueOf(this Signum));
0629: tempBI = Multiplication.multiplyByPositiveInt(
0630: tempBI, 10).add(
0631: BigInteger.valueOf(this Signum * 9));
0632: }
0633: // Rounding the improved subtracting
0634: leftOperand = new BigDecimal(tempBI, this .scale + 1);
0635: return leftOperand.round(mc);
0636: }
0637: }
0638: // No optimization is done
0639: return subtract(subtrahend).round(mc);
0640: }
0641:
0642: /** @ar.org.fitc.spec_ref */
0643: public BigDecimal multiply(BigDecimal multiplicand) {
0644: long newScale = (long) this .scale + multiplicand.scale;
0645:
0646: if ((this .isZero()) || (multiplicand.isZero())) {
0647: return zeroScaledBy(newScale);
0648: }
0649: /* Let be: this = [u1,s1] and multiplicand = [u2,s2] so:
0650: * this x multiplicand = [ s1 * s2 , s1 + s2 ] */
0651: if (this .bitLength + multiplicand.bitLength < 64) {
0652: return valueOf(this .smallValue * multiplicand.smallValue,
0653: toIntScale(newScale));
0654: }
0655: return new BigDecimal(this .getUnscaledValue().multiply(
0656: multiplicand.getUnscaledValue()), toIntScale(newScale));
0657: }
0658:
0659: /** @ar.org.fitc.spec_ref */
0660: public BigDecimal multiply(BigDecimal multiplicand, MathContext mc) {
0661: BigDecimal result = multiply(multiplicand);
0662:
0663: result.inplaceRound(mc);
0664: return result;
0665: }
0666:
0667: /** @ar.org.fitc.spec_ref */
0668: public BigDecimal divide(BigDecimal divisor, int scale,
0669: int roundingMode) {
0670: return divide(divisor, scale, RoundingMode
0671: .valueOf(roundingMode));
0672: }
0673:
0674: /** @ar.org.fitc.spec_ref */
0675: public BigDecimal divide(BigDecimal divisor, int scale,
0676: RoundingMode roundingMode) {
0677: // Let be: this = [u1,s1] and divisor = [u2,s2]
0678: if (roundingMode == null) {
0679: throw new NullPointerException();
0680: }
0681: if (divisor.isZero()) {
0682: // math.04=Division by zero
0683: throw new ArithmeticException(Messages.getString("math.04")); //$NON-NLS-1$
0684: }
0685:
0686: long diffScale = ((long) this .scale - divisor.scale) - scale;
0687: if (this .bitLength < 64 && divisor.bitLength < 64) {
0688: if (diffScale == 0) {
0689: return dividePrimitiveLongs(this .smallValue,
0690: divisor.smallValue, scale, roundingMode);
0691: } else if (diffScale > 0) {
0692: if (diffScale < LONG_TEN_POW.length
0693: && divisor.bitLength
0694: + LONG_TEN_POW_BIT_LENGTH[(int) diffScale] < 64) {
0695: return dividePrimitiveLongs(this .smallValue,
0696: divisor.smallValue
0697: * LONG_TEN_POW[(int) diffScale],
0698: scale, roundingMode);
0699: }
0700: } else { // diffScale < 0
0701: if (-diffScale < LONG_TEN_POW.length
0702: && this .bitLength
0703: + LONG_TEN_POW_BIT_LENGTH[(int) -diffScale] < 64) {
0704: return dividePrimitiveLongs(this .smallValue
0705: * LONG_TEN_POW[(int) -diffScale],
0706: divisor.smallValue, scale, roundingMode);
0707: }
0708:
0709: }
0710: }
0711: BigInteger scaledDividend = this .getUnscaledValue();
0712: BigInteger scaledDivisor = divisor.getUnscaledValue(); // for scaling of 'u2'
0713:
0714: if (diffScale > 0) {
0715: // Multiply 'u2' by: 10^((s1 - s2) - scale)
0716: scaledDivisor = Multiplication.multiplyByTenPow(
0717: scaledDivisor, (int) diffScale);
0718: } else if (diffScale < 0) {
0719: // Multiply 'u1' by: 10^(scale - (s1 - s2))
0720: scaledDividend = Multiplication.multiplyByTenPow(
0721: scaledDividend, (int) -diffScale);
0722: }
0723: return divideBigIntegers(scaledDividend, scaledDivisor, scale,
0724: roundingMode);
0725: }
0726:
0727: private static BigDecimal divideBigIntegers(
0728: BigInteger scaledDividend, BigInteger scaledDivisor,
0729: int scale, RoundingMode roundingMode) {
0730:
0731: BigInteger[] quotAndRem = scaledDividend
0732: .divideAndRemainder(scaledDivisor); // quotient and remainder
0733: // If after division there is a remainder...
0734: BigInteger quotient = quotAndRem[0];
0735: BigInteger remainder = quotAndRem[1];
0736: if (remainder.signum() == 0) {
0737: return new BigDecimal(quotient, scale);
0738: }
0739: int sign = scaledDividend.signum() * scaledDivisor.signum();
0740: int compRem; // 'compare to remainder'
0741: if (scaledDivisor.bitLength() < 63) { // 63 in order to avoid out of long after <<1
0742: long rem = remainder.longValue();
0743: long divisor = scaledDivisor.longValue();
0744: compRem = longCompareTo(Math.abs(rem) << 1, Math
0745: .abs(divisor));
0746: // To look if there is a carry
0747: compRem = roundingBehavior(quotient.testBit(0) ? 1 : 0,
0748: sign * (5 + compRem), roundingMode);
0749:
0750: } else {
0751: // Checking if: remainder * 2 >= scaledDivisor
0752: compRem = remainder.abs().shiftLeft(1).compareTo(
0753: scaledDivisor.abs());
0754: compRem = roundingBehavior(quotient.testBit(0) ? 1 : 0,
0755: sign * (5 + compRem), roundingMode);
0756: }
0757: if (compRem != 0) {
0758: if (quotient.bitLength() < 63) {
0759: return valueOf(quotient.longValue() + compRem, scale);
0760: }
0761: quotient = quotient.add(BigInteger.valueOf(compRem));
0762: return new BigDecimal(quotient, scale);
0763: }
0764: // Constructing the result with the appropriate unscaled value
0765: return new BigDecimal(quotient, scale);
0766: }
0767:
0768: private static BigDecimal dividePrimitiveLongs(long scaledDividend,
0769: long scaledDivisor, int scale, RoundingMode roundingMode) {
0770: long quotient = scaledDividend / scaledDivisor;
0771: long remainder = scaledDividend % scaledDivisor;
0772: int sign = Long.signum(scaledDividend)
0773: * Long.signum(scaledDivisor);
0774: if (remainder != 0) {
0775: // Checking if: remainder * 2 >= scaledDivisor
0776: int compRem; // 'compare to remainder'
0777: compRem = longCompareTo(Math.abs(remainder) << 1, Math
0778: .abs(scaledDivisor));
0779: // To look if there is a carry
0780: quotient += roundingBehavior(((int) quotient) & 1, sign
0781: * (5 + compRem), roundingMode);
0782: }
0783: // Constructing the result with the appropriate unscaled value
0784: return valueOf(quotient, scale);
0785: }
0786:
0787: /** @ar.org.fitc.spec_ref */
0788: public BigDecimal divide(BigDecimal divisor, int roundingMode) {
0789: return divide(divisor, scale, RoundingMode
0790: .valueOf(roundingMode));
0791: }
0792:
0793: /** @ar.org.fitc.spec_ref */
0794: public BigDecimal divide(BigDecimal divisor,
0795: RoundingMode roundingMode) {
0796: return divide(divisor, scale, roundingMode);
0797: }
0798:
0799: /** @ar.org.fitc.spec_ref */
0800: public BigDecimal divide(BigDecimal divisor) {
0801: BigInteger p = this .getUnscaledValue();
0802: BigInteger q = divisor.getUnscaledValue();
0803: BigInteger gcd; // greatest common divisor between 'p' and 'q'
0804: BigInteger quotAndRem[];
0805: long diffScale = (long) scale - divisor.scale;
0806: int newScale; // the new scale for final quotient
0807: int k; // number of factors "2" in 'q'
0808: int l = 0; // number of factors "5" in 'q'
0809: int i = 1;
0810: int lastPow = FIVE_POW.length - 1;
0811:
0812: if (divisor.isZero()) {
0813: // math.04=Division by zero
0814: throw new ArithmeticException(Messages.getString("math.04")); //$NON-NLS-1$
0815: }
0816: if (p.signum() == 0) {
0817: return zeroScaledBy(diffScale);
0818: }
0819: // To divide both by the GCD
0820: gcd = p.gcd(q);
0821: p = p.divide(gcd);
0822: q = q.divide(gcd);
0823: // To simplify all "2" factors of q, dividing by 2^k
0824: k = q.getLowestSetBit();
0825: q = q.shiftRight(k);
0826: // To simplify all "5" factors of q, dividing by 5^l
0827: do {
0828: quotAndRem = q.divideAndRemainder(FIVE_POW[i]);
0829: if (quotAndRem[1].signum() == 0) {
0830: l += i;
0831: if (i < lastPow) {
0832: i++;
0833: }
0834: q = quotAndRem[0];
0835: } else {
0836: if (i == 1) {
0837: break;
0838: }
0839: i = 1;
0840: }
0841: } while (true);
0842: // If abs(q) != 1 then the quotient is periodic
0843: if (!q.abs().equals(BigInteger.ONE)) {
0844: // math.05=Non-terminating decimal expansion; no exact representable decimal result.
0845: throw new ArithmeticException(Messages.getString("math.05")); //$NON-NLS-1$
0846: }
0847: // The sign of the is fixed and the quotient will be saved in 'p'
0848: if (q.signum() < 0) {
0849: p = p.negate();
0850: }
0851: // Checking if the new scale is out of range
0852: newScale = toIntScale(diffScale + Math.max(k, l));
0853: // k >= 0 and l >= 0 implies that k - l is in the 32-bit range
0854: i = k - l;
0855:
0856: p = (i > 0) ? Multiplication.multiplyByFivePow(p, i) : p
0857: .shiftLeft(-i);
0858: return new BigDecimal(p, newScale);
0859: }
0860:
0861: /** @ar.org.fitc.spec_ref */
0862: public BigDecimal divide(BigDecimal divisor, MathContext mc) {
0863: /* Calculating how many zeros must be append to 'dividend'
0864: * to obtain a quotient with at least 'mc.precision()' digits */
0865: long traillingZeros = mc.getPrecision() + 2L
0866: + divisor.aproxPrecision() - aproxPrecision();
0867: long diffScale = (long) scale - divisor.scale;
0868: long newScale = diffScale; // scale of the final quotient
0869: int compRem; // to compare the remainder
0870: int i = 1; // index
0871: int lastPow = TEN_POW.length - 1; // last power of ten
0872: BigInteger integerQuot; // for temporal results
0873: BigInteger quotAndRem[] = { getUnscaledValue() };
0874: // In special cases it reduces the problem to call the dual method
0875: if ((mc.getPrecision() == 0) || (this .isZero())
0876: || (divisor.isZero())) {
0877: return this .divide(divisor);
0878: }
0879: if (traillingZeros > 0) {
0880: // To append trailing zeros at end of dividend
0881: quotAndRem[0] = getUnscaledValue().multiply(
0882: Multiplication.powerOf10(traillingZeros));
0883: newScale += traillingZeros;
0884: }
0885: quotAndRem = quotAndRem[0].divideAndRemainder(divisor
0886: .getUnscaledValue());
0887: integerQuot = quotAndRem[0];
0888: // Calculating the exact quotient with at least 'mc.precision()' digits
0889: if (quotAndRem[1].signum() != 0) {
0890: // Checking if: 2 * remainder >= divisor ?
0891: compRem = quotAndRem[1].shiftLeft(1).compareTo(
0892: divisor.getUnscaledValue());
0893: // quot := quot * 10 + r; with 'r' in {-6,-5,-4, 0,+4,+5,+6}
0894: integerQuot = integerQuot.multiply(BigInteger.TEN).add(
0895: BigInteger.valueOf(quotAndRem[0].signum()
0896: * (5 + compRem)));
0897: newScale++;
0898: } else {
0899: // To strip trailing zeros until the preferred scale is reached
0900: while (!integerQuot.testBit(0)) {
0901: quotAndRem = integerQuot.divideAndRemainder(TEN_POW[i]);
0902: if ((quotAndRem[1].signum() == 0)
0903: && (newScale - i >= diffScale)) {
0904: newScale -= i;
0905: if (i < lastPow) {
0906: i++;
0907: }
0908: integerQuot = quotAndRem[0];
0909: } else {
0910: if (i == 1) {
0911: break;
0912: }
0913: i = 1;
0914: }
0915: }
0916: }
0917: // To perform rounding
0918: return new BigDecimal(integerQuot, toIntScale(newScale), mc);
0919: }
0920:
0921: /** @ar.org.fitc.spec_ref */
0922: public BigDecimal divideToIntegralValue(BigDecimal divisor) {
0923: BigInteger integralValue; // the integer of result
0924: BigInteger powerOfTen; // some power of ten
0925: BigInteger quotAndRem[] = { getUnscaledValue() };
0926: long newScale = (long) this .scale - divisor.scale;
0927: long tempScale = 0;
0928: int i = 1;
0929: int lastPow = TEN_POW.length - 1;
0930:
0931: if (divisor.isZero()) {
0932: // math.04=Division by zero
0933: throw new ArithmeticException(Messages.getString("math.04")); //$NON-NLS-1$
0934: }
0935: if ((divisor.aproxPrecision() + newScale > this
0936: .aproxPrecision() + 1L)
0937: || (this .isZero())) {
0938: /* If the divisor's integer part is greater than this's integer part,
0939: * the result must be zero with the appropriate scale */
0940: integralValue = BigInteger.ZERO;
0941: } else if (newScale == 0) {
0942: integralValue = getUnscaledValue().divide(
0943: divisor.getUnscaledValue());
0944: } else if (newScale > 0) {
0945: powerOfTen = Multiplication.powerOf10(newScale);
0946: integralValue = getUnscaledValue().divide(
0947: divisor.getUnscaledValue().multiply(powerOfTen));
0948: integralValue = integralValue.multiply(powerOfTen);
0949: } else {// (newScale < 0)
0950: powerOfTen = Multiplication.powerOf10(-newScale);
0951: integralValue = getUnscaledValue().multiply(powerOfTen)
0952: .divide(divisor.getUnscaledValue());
0953: // To strip trailing zeros approximating to the preferred scale
0954: while (!integralValue.testBit(0)) {
0955: quotAndRem = integralValue
0956: .divideAndRemainder(TEN_POW[i]);
0957: if ((quotAndRem[1].signum() == 0)
0958: && (tempScale - i >= newScale)) {
0959: tempScale -= i;
0960: if (i < lastPow) {
0961: i++;
0962: }
0963: integralValue = quotAndRem[0];
0964: } else {
0965: if (i == 1) {
0966: break;
0967: }
0968: i = 1;
0969: }
0970: }
0971: newScale = tempScale;
0972: }
0973: return ((integralValue.signum() == 0) ? zeroScaledBy(newScale)
0974: : new BigDecimal(integralValue, toIntScale(newScale)));
0975: }
0976:
0977: /** @ar.org.fitc.spec_ref */
0978: public BigDecimal divideToIntegralValue(BigDecimal divisor,
0979: MathContext mc) {
0980: int mcPrecision = mc.getPrecision();
0981: int diffPrecision = this .precision() - divisor.precision();
0982: int lastPow = TEN_POW.length - 1;
0983: long diffScale = (long) this .scale - divisor.scale;
0984: long newScale = diffScale;
0985: long quotPrecision = diffPrecision - diffScale + 1;
0986: BigInteger quotAndRem[] = new BigInteger[2];
0987: // In special cases it call the dual method
0988: if ((mcPrecision == 0) || (this .isZero()) || (divisor.isZero())) {
0989: return this .divideToIntegralValue(divisor);
0990: }
0991: // Let be: this = [u1,s1] and divisor = [u2,s2]
0992: if (quotPrecision <= 0) {
0993: quotAndRem[0] = BigInteger.ZERO;
0994: } else if (diffScale == 0) {
0995: // CASE s1 == s2: to calculate u1 / u2
0996: quotAndRem[0] = this .getUnscaledValue().divide(
0997: divisor.getUnscaledValue());
0998: } else if (diffScale > 0) {
0999: // CASE s1 >= s2: to calculate u1 / (u2 * 10^(s1-s2)
1000: quotAndRem[0] = this .getUnscaledValue().divide(
1001: divisor.getUnscaledValue().multiply(
1002: Multiplication.powerOf10(diffScale)));
1003: // To chose 10^newScale to get a quotient with at least 'mc.precision()' digits
1004: newScale = Math.min(diffScale, Math.max(mcPrecision
1005: - quotPrecision + 1, 0));
1006: // To calculate: (u1 / (u2 * 10^(s1-s2)) * 10^newScale
1007: quotAndRem[0] = quotAndRem[0].multiply(Multiplication
1008: .powerOf10(newScale));
1009: } else {// CASE s2 > s1:
1010: /* To calculate the minimum power of ten, such that the quotient
1011: * (u1 * 10^exp) / u2 has at least 'mc.precision()' digits. */
1012: long exp = Math.min(-diffScale, Math.max((long) mcPrecision
1013: - diffPrecision, 0));
1014: long compRemDiv;
1015: // Let be: (u1 * 10^exp) / u2 = [q,r]
1016: quotAndRem = this .getUnscaledValue().multiply(
1017: Multiplication.powerOf10(exp)).divideAndRemainder(
1018: divisor.getUnscaledValue());
1019: newScale += exp; // To fix the scale
1020: exp = -newScale; // The remaining power of ten
1021: // If after division there is a remainder...
1022: if ((quotAndRem[1].signum() != 0) && (exp > 0)) {
1023: // Log10(r) + ((s2 - s1) - exp) > mc.precision ?
1024: compRemDiv = (new BigDecimal(quotAndRem[1]))
1025: .precision()
1026: + exp - divisor.precision();
1027: if (compRemDiv == 0) {
1028: // To calculate: (r * 10^exp2) / u2
1029: quotAndRem[1] = quotAndRem[1].multiply(
1030: Multiplication.powerOf10(exp)).divide(
1031: divisor.getUnscaledValue());
1032: compRemDiv = Math.abs(quotAndRem[1].signum());
1033: }
1034: if (compRemDiv > 0) {
1035: // The quotient won't fit in 'mc.precision()' digits
1036: // math.06=Division impossible
1037: throw new ArithmeticException(Messages
1038: .getString("math.06")); //$NON-NLS-1$
1039: }
1040: }
1041: }
1042: // Fast return if the quotient is zero
1043: if (quotAndRem[0].signum() == 0) {
1044: return zeroScaledBy(diffScale);
1045: }
1046: BigInteger strippedBI = quotAndRem[0];
1047: BigDecimal integralValue = new BigDecimal(quotAndRem[0]);
1048: long resultPrecision = integralValue.precision();
1049: int i = 1;
1050: // To strip trailing zeros until the specified precision is reached
1051: while (!strippedBI.testBit(0)) {
1052: quotAndRem = strippedBI.divideAndRemainder(TEN_POW[i]);
1053: if ((quotAndRem[1].signum() == 0)
1054: && ((resultPrecision - i >= mcPrecision) || (newScale
1055: - i >= diffScale))) {
1056: resultPrecision -= i;
1057: newScale -= i;
1058: if (i < lastPow) {
1059: i++;
1060: }
1061: strippedBI = quotAndRem[0];
1062: } else {
1063: if (i == 1) {
1064: break;
1065: }
1066: i = 1;
1067: }
1068: }
1069: // To check if the result fit in 'mc.precision()' digits
1070: if (resultPrecision > mcPrecision) {
1071: // math.06=Division impossible
1072: throw new ArithmeticException(Messages.getString("math.06")); //$NON-NLS-1$
1073: }
1074: integralValue.scale = toIntScale(newScale);
1075: integralValue.setUnscaledValue(strippedBI);
1076: return integralValue;
1077: }
1078:
1079: /** @ar.org.fitc.spec_ref */
1080: public BigDecimal remainder(BigDecimal divisor) {
1081: return divideAndRemainder(divisor)[1];
1082: }
1083:
1084: /** @ar.org.fitc.spec_ref */
1085: public BigDecimal remainder(BigDecimal divisor, MathContext mc) {
1086: return divideAndRemainder(divisor, mc)[1];
1087: }
1088:
1089: /** @ar.org.fitc.spec_ref */
1090: public BigDecimal[] divideAndRemainder(BigDecimal divisor) {
1091: BigDecimal quotAndRem[] = new BigDecimal[2];
1092:
1093: quotAndRem[0] = this .divideToIntegralValue(divisor);
1094: quotAndRem[1] = this .subtract(quotAndRem[0].multiply(divisor));
1095: return quotAndRem;
1096: }
1097:
1098: /** @ar.org.fitc.spec_ref */
1099: public BigDecimal[] divideAndRemainder(BigDecimal divisor,
1100: MathContext mc) {
1101: BigDecimal quotAndRem[] = new BigDecimal[2];
1102:
1103: quotAndRem[0] = this .divideToIntegralValue(divisor, mc);
1104: quotAndRem[1] = this .subtract(quotAndRem[0].multiply(divisor));
1105: return quotAndRem;
1106: }
1107:
1108: /** @ar.org.fitc.spec_ref */
1109: public BigDecimal pow(int n) {
1110: if (n == 0) {
1111: return ONE;
1112: }
1113: if ((n < 0) || (n > 999999999)) {
1114: // math.07=Invalid Operation
1115: throw new ArithmeticException(Messages.getString("math.07")); //$NON-NLS-1$
1116: }
1117: long newScale = scale * (long) n;
1118: // Let be: this = [u,s] so: this^n = [u^n, s*n]
1119: return ((isZero()) ? zeroScaledBy(newScale) : new BigDecimal(
1120: getUnscaledValue().pow(n), toIntScale(newScale)));
1121: }
1122:
1123: /** @ar.org.fitc.spec_ref */
1124: public BigDecimal pow(int n, MathContext mc) {
1125: // The ANSI standard X3.274-1996 algorithm
1126: int m = Math.abs(n);
1127: int mcPrecision = mc.getPrecision();
1128: int elength = (int) Math.log10(m) + 1; // decimal digits in 'n'
1129: int oneBitMask; // mask of bits
1130: BigDecimal accum; // the single accumulator
1131: MathContext newPrecision = mc; // MathContext by default
1132:
1133: // In particular cases, it reduces the problem to call the other 'pow()'
1134: if ((n == 0) || ((isZero()) && (n > 0))) {
1135: return pow(n);
1136: }
1137: if ((m > 999999999) || ((mcPrecision == 0) && (n < 0))
1138: || ((mcPrecision > 0) && (elength > mcPrecision))) {
1139: // math.07=Invalid Operation
1140: throw new ArithmeticException(Messages.getString("math.07")); //$NON-NLS-1$
1141: }
1142: if (mcPrecision > 0) {
1143: newPrecision = new MathContext(mcPrecision + elength + 1,
1144: mc.getRoundingMode());
1145: }
1146: // The result is calculated as if 'n' were positive
1147: accum = round(newPrecision);
1148: oneBitMask = Integer.highestOneBit(m) >> 1;
1149:
1150: while (oneBitMask > 0) {
1151: accum = accum.multiply(accum, newPrecision);
1152: if ((m & oneBitMask) == oneBitMask) {
1153: accum = accum.multiply(this , newPrecision);
1154: }
1155: oneBitMask >>= 1;
1156: }
1157: // If 'n' is negative, the value is divided into 'ONE'
1158: if (n < 0) {
1159: accum = ONE.divide(accum, newPrecision);
1160: }
1161: // The final value is rounded to the destination precision
1162: accum.inplaceRound(mc);
1163: return accum;
1164: }
1165:
1166: /** @ar.org.fitc.spec_ref */
1167: public BigDecimal abs() {
1168: return ((signum() < 0) ? negate() : this );
1169: }
1170:
1171: /** @ar.org.fitc.spec_ref */
1172: public BigDecimal abs(MathContext mc) {
1173: return round(mc).abs();
1174: }
1175:
1176: /** @ar.org.fitc.spec_ref */
1177: public BigDecimal negate() {
1178: if (bitLength < 63
1179: || (bitLength == 63 && smallValue != Long.MIN_VALUE)) {
1180: return valueOf(-smallValue, scale);
1181: }
1182: return new BigDecimal(getUnscaledValue().negate(), scale);
1183: }
1184:
1185: /** @ar.org.fitc.spec_ref */
1186: public BigDecimal negate(MathContext mc) {
1187: return round(mc).negate();
1188: }
1189:
1190: /** @ar.org.fitc.spec_ref */
1191: public BigDecimal plus() {
1192: return this ;
1193: }
1194:
1195: /** @ar.org.fitc.spec_ref */
1196: public BigDecimal plus(MathContext mc) {
1197: return round(mc);
1198: }
1199:
1200: /** @ar.org.fitc.spec_ref */
1201: public int signum() {
1202: if (bitLength < 64) {
1203: return Long.signum(this .smallValue);
1204: }
1205: return getUnscaledValue().signum();
1206: }
1207:
1208: private boolean isZero() {
1209: //Watch out: -1 has a bitLength=0
1210: return bitLength == 0 && this .smallValue != -1;
1211: }
1212:
1213: /** @ar.org.fitc.spec_ref */
1214: public int scale() {
1215: return scale;
1216: }
1217:
1218: /** @ar.org.fitc.spec_ref */
1219: public int precision() {
1220: // Checking if the precision already was calculated
1221: if (precision > 0) {
1222: return precision;
1223: }
1224: int bitLength = this .bitLength;
1225: int decimalDigits = 1; // the precision to be calculated
1226: double doubleUnsc = 1; // intVal in 'double'
1227:
1228: if (bitLength < 1024) {
1229: // To calculate the precision for small numbers
1230: if (bitLength >= 64) {
1231: doubleUnsc = getUnscaledValue().doubleValue();
1232: } else if (bitLength >= 1) {
1233: doubleUnsc = smallValue;
1234: }
1235: decimalDigits += Math.log10(Math.abs(doubleUnsc));
1236: } else {// (bitLength >= 1024)
1237: /* To calculate the precision for large numbers
1238: * Note that: 2 ^(bitlength() - 1) <= intVal < 10 ^(precision()) */
1239: decimalDigits += (bitLength - 1) * LOG10_2;
1240: // If after division the number isn't zero, exists an aditional digit
1241: if (getUnscaledValue().divide(
1242: Multiplication.powerOf10(decimalDigits)).signum() != 0) {
1243: decimalDigits++;
1244: }
1245: }
1246: precision = decimalDigits;
1247: return precision;
1248: }
1249:
1250: /** @ar.org.fitc.spec_ref */
1251: public BigInteger unscaledValue() {
1252: return getUnscaledValue();
1253: }
1254:
1255: /** @ar.org.fitc.spec_ref */
1256: public BigDecimal round(MathContext mc) {
1257: BigDecimal this BD = new BigDecimal(getUnscaledValue(), scale);
1258:
1259: this BD.inplaceRound(mc);
1260: return this BD;
1261: }
1262:
1263: /** @ar.org.fitc.spec_ref */
1264: public BigDecimal setScale(int newScale, RoundingMode roundingMode) {
1265: if (roundingMode == null) {
1266: throw new NullPointerException();
1267: }
1268: long diffScale = newScale - (long) scale;
1269: // Let be: 'this' = [u,s]
1270: if (diffScale == 0) {
1271: return this ;
1272: }
1273: if (diffScale > 0) {
1274: // return [u * 10^(s2 - s), newScale]
1275: if (diffScale < LONG_TEN_POW.length
1276: && (this .bitLength + LONG_TEN_POW_BIT_LENGTH[(int) diffScale]) < 64) {
1277: return valueOf(this .smallValue
1278: * LONG_TEN_POW[(int) diffScale], newScale);
1279: }
1280: return new BigDecimal(Multiplication.multiplyByTenPow(
1281: getUnscaledValue(), (int) diffScale), newScale);
1282: }
1283: // diffScale < 0
1284: // return [u,s] / [1,newScale] with the appropriate scale and rounding
1285: if (this .bitLength < 64 && -diffScale < LONG_TEN_POW.length) {
1286: return dividePrimitiveLongs(this .smallValue,
1287: LONG_TEN_POW[(int) -diffScale], newScale,
1288: roundingMode);
1289: }
1290: return divideBigIntegers(this .getUnscaledValue(),
1291: Multiplication.powerOf10(-diffScale), newScale,
1292: roundingMode);
1293: }
1294:
1295: /** @ar.org.fitc.spec_ref */
1296: public BigDecimal setScale(int newScale, int roundingMode) {
1297: return setScale(newScale, RoundingMode.valueOf(roundingMode));
1298: }
1299:
1300: /** @ar.org.fitc.spec_ref */
1301: public BigDecimal setScale(int newScale) {
1302: return setScale(newScale, RoundingMode.UNNECESSARY);
1303: }
1304:
1305: /** @ar.org.fitc.spec_ref */
1306: public BigDecimal movePointLeft(int n) {
1307: return movePoint(scale + (long) n);
1308: }
1309:
1310: private BigDecimal movePoint(long newScale) {
1311: if (isZero()) {
1312: return zeroScaledBy(Math.max(newScale, 0));
1313: }
1314: /* When: 'n'== Integer.MIN_VALUE isn't possible to call to movePointRight(-n)
1315: * since -Integer.MIN_VALUE == Integer.MIN_VALUE */
1316: if (newScale >= 0) {
1317: if (bitLength < 64) {
1318: return valueOf(smallValue, toIntScale(newScale));
1319: }
1320: return new BigDecimal(getUnscaledValue(),
1321: toIntScale(newScale));
1322: }
1323: if (-newScale < LONG_TEN_POW.length
1324: && bitLength + LONG_TEN_POW_BIT_LENGTH[(int) -newScale] < 64) {
1325: return valueOf(smallValue * LONG_TEN_POW[(int) -newScale],
1326: 0);
1327: }
1328: return new BigDecimal(Multiplication.multiplyByTenPow(
1329: getUnscaledValue(), (int) -newScale), 0);
1330: }
1331:
1332: /** @ar.org.fitc.spec_ref */
1333: public BigDecimal movePointRight(int n) {
1334: return movePoint(scale - (long) n);
1335: }
1336:
1337: /** @ar.org.fitc.spec_ref */
1338: public BigDecimal scaleByPowerOfTen(int n) {
1339: long newScale = scale - (long) n;
1340: if (bitLength < 64) {
1341: //Taking care when a 0 is to be scaled
1342: if (smallValue == 0) {
1343: return zeroScaledBy(newScale);
1344: }
1345: return valueOf(smallValue, toIntScale(newScale));
1346: }
1347: return new BigDecimal(getUnscaledValue(), toIntScale(newScale));
1348: }
1349:
1350: /** @ar.org.fitc.spec_ref */
1351: public BigDecimal stripTrailingZeros() {
1352: int i = 1; // 1 <= i <= 18
1353: int lastPow = TEN_POW.length - 1;
1354: long newScale = scale;
1355:
1356: if (isZero()) {
1357: return new BigDecimal("0");
1358: }
1359: BigInteger strippedBI = getUnscaledValue();
1360: BigInteger[] quotAndRem;
1361:
1362: // while the number is even...
1363: while (!strippedBI.testBit(0)) {
1364: // To divide by 10^i
1365: quotAndRem = strippedBI.divideAndRemainder(TEN_POW[i]);
1366: // To look the remainder
1367: if (quotAndRem[1].signum() == 0) {
1368: // To adjust the scale
1369: newScale -= i;
1370: if (i < lastPow) {
1371: // To set to the next power
1372: i++;
1373: }
1374: strippedBI = quotAndRem[0];
1375: } else {
1376: if (i == 1) {
1377: // 'this' has no more trailing zeros
1378: break;
1379: }
1380: // To set to the smallest power of ten
1381: i = 1;
1382: }
1383: }
1384: return new BigDecimal(strippedBI, toIntScale(newScale));
1385: }
1386:
1387: /** @ar.org.fitc.spec_ref */
1388: public int compareTo(BigDecimal val) {
1389: int this Sign = signum();
1390: int valueSign = val.signum();
1391:
1392: if (this Sign == valueSign) {
1393: if (this .scale == val.scale && this .bitLength < 64
1394: && val.bitLength < 64) {
1395: return (smallValue < val.smallValue) ? -1
1396: : (smallValue > val.smallValue) ? 1 : 0;
1397: }
1398: long diffScale = (long) this .scale - val.scale;
1399: int diffPrecision = this .aproxPrecision()
1400: - val.aproxPrecision();
1401: if (diffPrecision > diffScale + 1) {
1402: return this Sign;
1403: } else if (diffPrecision < diffScale - 1) {
1404: return -this Sign;
1405: } else {// thisSign == val.signum() and diffPrecision is aprox. diffScale
1406: BigInteger this Unscaled = this .getUnscaledValue();
1407: BigInteger valUnscaled = val.getUnscaledValue();
1408: // If any of both precision is bigger, append zeros to the shorter one
1409: if (diffScale < 0) {
1410: this Unscaled = this Unscaled.multiply(Multiplication
1411: .powerOf10(-diffScale));
1412: } else if (diffScale > 0) {
1413: valUnscaled = valUnscaled.multiply(Multiplication
1414: .powerOf10(diffScale));
1415: }
1416: return this Unscaled.compareTo(valUnscaled);
1417: }
1418: } else if (this Sign < valueSign) {
1419: return -1;
1420: } else {
1421: return 1;
1422: }
1423: }
1424:
1425: /** @ar.org.fitc.spec_ref */
1426: @Override
1427: public boolean equals(Object x) {
1428: if (this == x) {
1429: return true;
1430: }
1431: if (x instanceof BigDecimal) {
1432: BigDecimal x1 = (BigDecimal) x;
1433: return x1.scale == scale
1434: && (bitLength < 64 ? (x1.smallValue == smallValue)
1435: : intVal.equals(x1.intVal));
1436:
1437: }
1438: return false;
1439: }
1440:
1441: /** @ar.org.fitc.spec_ref */
1442: public BigDecimal min(BigDecimal val) {
1443: return ((compareTo(val) <= 0) ? this : val);
1444: }
1445:
1446: /** @ar.org.fitc.spec_ref */
1447: public BigDecimal max(BigDecimal val) {
1448: return ((compareTo(val) >= 0) ? this : val);
1449: }
1450:
1451: /** @ar.org.fitc.spec_ref */
1452: @Override
1453: public int hashCode() {
1454: if (hashCode != 0) {
1455: return hashCode;
1456: }
1457: if (bitLength < 64) {
1458: hashCode = (int) (smallValue & 0xffffffff);
1459: hashCode = 33 * hashCode
1460: + (int) ((smallValue >> 32) & 0xffffffff);
1461: hashCode = 17 * hashCode + scale;
1462: return hashCode;
1463: }
1464: hashCode = 17 * intVal.hashCode() + scale;
1465: return hashCode;
1466: }
1467:
1468: /** @ar.org.fitc.spec_ref */
1469: @Override
1470: public String toString() {
1471: if (toStringImage != null) {
1472: return toStringImage;
1473: }
1474: if (bitLength < 32) {
1475: toStringImage = Conversion.toDecimalScaledString(
1476: smallValue, scale);
1477: return toStringImage;
1478: }
1479: String intString = getUnscaledValue().toString();
1480: if (scale == 0) {
1481: return intString;
1482: }
1483: int begin = (getUnscaledValue().signum() < 0) ? 2 : 1;
1484: int end = intString.length();
1485: long exponent = -(long) scale + end - begin;
1486: StringBuffer result = new StringBuffer();
1487:
1488: result.append(intString);
1489: if ((scale > 0) && (exponent >= -6)) {
1490: if (exponent >= 0) {
1491: result.insert(end - scale, '.');
1492: } else {
1493: result.insert(begin - 1, "0."); //$NON-NLS-1$
1494: result.insert(begin + 1, CH_ZEROS, 0,
1495: -(int) exponent - 1);
1496: }
1497: } else {
1498: if (end - begin >= 1) {
1499: result.insert(begin, '.');
1500: end++;
1501: }
1502: result.insert(end, 'E');
1503: if (exponent > 0) {
1504: result.insert(++end, '+');
1505: }
1506: result.insert(++end, Long.toString(exponent));
1507: }
1508: toStringImage = result.toString();
1509: return toStringImage;
1510: }
1511:
1512: /** @ar.org.fitc.spec_ref */
1513: public String toEngineeringString() {
1514: String intString = getUnscaledValue().toString();
1515: if (scale == 0) {
1516: return intString;
1517: }
1518: int begin = (getUnscaledValue().signum() < 0) ? 2 : 1;
1519: int end = intString.length();
1520: long exponent = -(long) scale + end - begin;
1521: StringBuffer result = new StringBuffer(intString);
1522:
1523: if ((scale > 0) && (exponent >= -6)) {
1524: if (exponent >= 0) {
1525: result.insert(end - scale, '.');
1526: } else {
1527: result.insert(begin - 1, "0."); //$NON-NLS-1$
1528: result.insert(begin + 1, CH_ZEROS, 0,
1529: -(int) exponent - 1);
1530: }
1531: } else {
1532: int delta = end - begin;
1533: int rem = (int) (exponent % 3);
1534:
1535: if (rem != 0) {
1536: // adjust exponent so it is a multiple of three
1537: if (getUnscaledValue().signum() == 0) {
1538: // zero value
1539: rem = (rem < 0) ? -rem : 3 - rem;
1540: exponent += rem;
1541: } else {
1542: // nonzero value
1543: rem = (rem < 0) ? rem + 3 : rem;
1544: exponent -= rem;
1545: begin += rem;
1546: }
1547: if (delta < 3) {
1548: for (int i = rem - delta; i > 0; i--) {
1549: result.insert(end++, '0');
1550: }
1551: }
1552: }
1553: if (end - begin >= 1) {
1554: result.insert(begin, '.');
1555: end++;
1556: }
1557: if (exponent != 0) {
1558: result.insert(end, 'E');
1559: if (exponent > 0) {
1560: result.insert(++end, '+');
1561: }
1562: result.insert(++end, Long.toString(exponent));
1563: }
1564: }
1565: return result.toString();
1566: }
1567:
1568: /** @ar.org.fitc.spec_ref */
1569: public String toPlainString() {
1570: String intStr = getUnscaledValue().toString();
1571: if ((scale == 0) || ((isZero()) && (scale < 0))) {
1572: return intStr;
1573: }
1574: int begin = (signum() < 0) ? 1 : 0;
1575: int delta = scale;
1576: // We take space for all digits, plus a possible decimal point, plus 'scale'
1577: StringBuffer result = new StringBuffer(intStr.length() + 1
1578: + Math.abs(scale));
1579:
1580: if (begin == 1) {
1581: // If the number is negative, we insert a '-' character at front
1582: result.append('-');
1583: }
1584: if (scale > 0) {
1585: delta -= (intStr.length() - begin);
1586: if (delta >= 0) {
1587: result.append("0."); //$NON-NLS-1$
1588: // To append zeros after the decimal point
1589: for (; delta > CH_ZEROS.length; delta -= CH_ZEROS.length) {
1590: result.append(CH_ZEROS);
1591: }
1592: result.append(CH_ZEROS, 0, delta);
1593: result.append(intStr.substring(begin));
1594: } else {
1595: delta = begin - delta;
1596: result.append(intStr.substring(begin, delta));
1597: result.append('.');
1598: result.append(intStr.substring(delta));
1599: }
1600: } else {// (scale <= 0)
1601: result.append(intStr.substring(begin));
1602: // To append trailing zeros
1603: for (; delta < -CH_ZEROS.length; delta += CH_ZEROS.length) {
1604: result.append(CH_ZEROS);
1605: }
1606: result.append(CH_ZEROS, 0, -delta);
1607: }
1608: return result.toString();
1609: }
1610:
1611: /** @ar.org.fitc.spec_ref */
1612: public BigInteger toBigInteger() {
1613: if ((scale == 0) || (isZero())) {
1614: return getUnscaledValue();
1615: } else if (scale < 0) {
1616: return getUnscaledValue().multiply(
1617: Multiplication.powerOf10(-(long) scale));
1618: } else {// (scale > 0)
1619: return getUnscaledValue().divide(
1620: Multiplication.powerOf10(scale));
1621: }
1622: }
1623:
1624: /** @ar.org.fitc.spec_ref */
1625: public BigInteger toBigIntegerExact() {
1626: if ((scale == 0) || (isZero())) {
1627: return getUnscaledValue();
1628: } else if (scale < 0) {
1629: return getUnscaledValue().multiply(
1630: Multiplication.powerOf10(-(long) scale));
1631: } else {// (scale > 0)
1632: BigInteger[] integerAndFraction;
1633: // An optimization before do a heavy division
1634: if ((scale > aproxPrecision())
1635: || (scale > getUnscaledValue().getLowestSetBit())) {
1636: // math.08=Rounding necessary
1637: throw new ArithmeticException(Messages
1638: .getString("math.08")); //$NON-NLS-1$
1639: }
1640: integerAndFraction = getUnscaledValue().divideAndRemainder(
1641: Multiplication.powerOf10(scale));
1642: if (integerAndFraction[1].signum() != 0) {
1643: // It exists a non-zero fractional part
1644: // math.08=Rounding necessary
1645: throw new ArithmeticException(Messages
1646: .getString("math.08")); //$NON-NLS-1$
1647: }
1648: return integerAndFraction[0];
1649: }
1650: }
1651:
1652: /** @ar.org.fitc.spec_ref */
1653: @Override
1654: public long longValue() {
1655: /* If scale <= -64 there are at least 64 trailing bits zero in 10^(-scale).
1656: * If the scale is positive and very large the long value could be zero. */
1657: return ((scale <= -64) || (scale > aproxPrecision()) ? 0L
1658: : toBigInteger().longValue());
1659: }
1660:
1661: /** @ar.org.fitc.spec_ref */
1662: public long longValueExact() {
1663: return valueExact(64);
1664: }
1665:
1666: /** @ar.org.fitc.spec_ref */
1667: @Override
1668: public int intValue() {
1669: /* If scale <= -32 there are at least 32 trailing bits zero in 10^(-scale).
1670: * If the scale is positive and very large the long value could be zero. */
1671: return ((scale <= -32) || (scale > aproxPrecision()) ? 0
1672: : toBigInteger().intValue());
1673: }
1674:
1675: /** @ar.org.fitc.spec_ref */
1676: public int intValueExact() {
1677: return (int) valueExact(32);
1678: }
1679:
1680: /** @ar.org.fitc.spec_ref */
1681: public short shortValueExact() {
1682: return (short) valueExact(16);
1683: }
1684:
1685: /** @ar.org.fitc.spec_ref */
1686: public byte byteValueExact() {
1687: return (byte) valueExact(8);
1688: }
1689:
1690: /** @ar.org.fitc.spec_ref */
1691: @Override
1692: public float floatValue() {
1693: /* A similar code like in doubleValue() could be repeated here,
1694: * but this simple implementation is quite efficient. */
1695: float floatResult = signum();
1696: long powerOfTwo = this .bitLength - (long) (scale / LOG10_2);
1697: if ((powerOfTwo < -149) || (floatResult == 0.0f)) {
1698: // Cases which 'this' is very small
1699: floatResult *= 0.0f;
1700: } else if (powerOfTwo > 129) {
1701: // Cases which 'this' is very large
1702: floatResult *= Float.POSITIVE_INFINITY;
1703: } else {
1704: floatResult = (float) doubleValue();
1705: }
1706: return floatResult;
1707: }
1708:
1709: /** @ar.org.fitc.spec_ref */
1710: @Override
1711: public double doubleValue() {
1712: int sign = signum();
1713: int exponent = 1076; // bias + 53
1714: int lowestSetBit;
1715: int discardedSize;
1716: long powerOfTwo = this .bitLength - (long) (scale / LOG10_2);
1717: long bits; // IEEE-754 Standard
1718: long tempBits; // for temporal calculations
1719: BigInteger mantisa;
1720:
1721: if ((powerOfTwo < -1074) || (sign == 0)) {
1722: // Cases which 'this' is very small
1723: return (sign * 0.0d);
1724: } else if (powerOfTwo > 1025) {
1725: // Cases which 'this' is very large
1726: return (sign * Double.POSITIVE_INFINITY);
1727: }
1728: mantisa = getUnscaledValue().abs();
1729: // Let be: this = [u,s], with s > 0
1730: if (scale <= 0) {
1731: // mantisa = abs(u) * 10^s
1732: mantisa = mantisa
1733: .multiply(Multiplication.powerOf10(-scale));
1734: } else {// (scale > 0)
1735: BigInteger quotAndRem[];
1736: BigInteger powerOfTen = Multiplication.powerOf10(scale);
1737: int k = 100 - (int) powerOfTwo;
1738: int compRem;
1739:
1740: if (k > 0) {
1741: /* Computing (mantisa * 2^k) , where 'k' is a enough big
1742: * power of '2' to can divide by 10^s */
1743: mantisa = mantisa.shiftLeft(k);
1744: exponent -= k;
1745: }
1746: // Computing (mantisa * 2^k) / 10^s
1747: quotAndRem = mantisa.divideAndRemainder(powerOfTen);
1748: // To check if the fractional part >= 0.5
1749: compRem = quotAndRem[1].shiftLeft(1).compareTo(powerOfTen);
1750: // To add two rounded bits at end of mantisa
1751: mantisa = quotAndRem[0]
1752: .shiftLeft(2)
1753: .add(
1754: BigInteger
1755: .valueOf((compRem * (compRem + 3)) / 2 + 1));
1756: exponent -= 2;
1757: }
1758: lowestSetBit = mantisa.getLowestSetBit();
1759: discardedSize = mantisa.bitLength() - 54;
1760: if (discardedSize > 0) {// (n > 54)
1761: // mantisa = (abs(u) * 10^s) >> (n - 54)
1762: bits = mantisa.shiftRight(discardedSize).longValue();
1763: tempBits = bits;
1764: // #bits = 54, to check if the discarded fraction produces a carry
1765: if ((((bits & 1) == 1) && (lowestSetBit < discardedSize))
1766: || ((bits & 3) == 3)) {
1767: bits += 2;
1768: }
1769: } else {// (n <= 54)
1770: // mantisa = (abs(u) * 10^s) << (54 - n)
1771: bits = mantisa.longValue() << -discardedSize;
1772: tempBits = bits;
1773: // #bits = 54, to check if the discarded fraction produces a carry:
1774: if ((bits & 3) == 3) {
1775: bits += 2;
1776: }
1777: }
1778: // Testing bit 54 to check if the carry creates a new binary digit
1779: if ((bits & 0x40000000000000L) == 0) {
1780: // To drop the last bit of mantisa (first discarded)
1781: bits >>= 1;
1782: // exponent = 2^(s-n+53+bias)
1783: exponent += discardedSize;
1784: } else {// #bits = 54
1785: bits >>= 2;
1786: exponent += discardedSize + 1;
1787: }
1788: // To test if the 53-bits number fits in 'double'
1789: if (exponent > 2046) {// (exponent - bias > 1023)
1790: return (sign * Double.POSITIVE_INFINITY);
1791: } else if (exponent <= 0) {// (exponent - bias <= -1023)
1792: // Denormalized numbers (having exponent == 0)
1793: if (exponent < -53) {// exponent - bias < -1076
1794: return (sign * 0.0d);
1795: }
1796: // -1076 <= exponent - bias <= -1023
1797: // To discard '- exponent + 1' bits
1798: bits = tempBits >> 1;
1799: tempBits = bits & (-1L >>> (63 + exponent));
1800: bits >>= (-exponent);
1801: // To test if after discard bits, a new carry is generated
1802: if (((bits & 3) == 3)
1803: || (((bits & 1) == 1) && (tempBits != 0) && (lowestSetBit < discardedSize))) {
1804: bits += 1;
1805: }
1806: exponent = 0;
1807: bits >>= 1;
1808: }
1809: // Construct the 64 double bits: [sign(1), exponent(11), mantisa(52)]
1810: bits = (sign & 0x8000000000000000L) | ((long) exponent << 52)
1811: | (bits & 0xFFFFFFFFFFFFFL);
1812: return Double.longBitsToDouble(bits);
1813: }
1814:
1815: /** @ar.org.fitc.spec_ref */
1816: public BigDecimal ulp() {
1817: return valueOf(1, scale);
1818: }
1819:
1820: /* Private Methods */
1821:
1822: /**
1823: * It does all rounding work of the public method <code>round(MathContext)</code>,
1824: * performing an inplace rounding without creating a new object.
1825: * @param mc the <code>MathContext</code> for perform the rounding.
1826: * @see #round(MathContext).
1827: */
1828: private void inplaceRound(MathContext mc) {
1829: int mcPrecision = mc.getPrecision();
1830: if (aproxPrecision() - mcPrecision <= 0 || mcPrecision == 0) {
1831: return;
1832: }
1833: int discardedPrecision = precision() - mcPrecision;
1834: // If no rounding is necessary it returns immediately
1835: if ((discardedPrecision <= 0)) {
1836: return;
1837: }
1838: // When the number is small perform an efficient rounding
1839: if (this .bitLength < 64) {
1840: smallRound(mc, discardedPrecision);
1841: return;
1842: }
1843: // Getting the integer part and the discarded fraction
1844: BigInteger sizeOfFraction = Multiplication
1845: .powerOf10(discardedPrecision);
1846: BigInteger[] integerAndFraction = getUnscaledValue()
1847: .divideAndRemainder(sizeOfFraction);
1848: long newScale = (long) scale - discardedPrecision;
1849: int compRem;
1850: BigDecimal tempBD;
1851: // If the discarded fraction is non-zero, perform rounding
1852: if (integerAndFraction[1].signum() != 0) {
1853: // To check if the discarded fraction >= 0.5
1854: compRem = (integerAndFraction[1].abs().shiftLeft(1)
1855: .compareTo(sizeOfFraction));
1856: // To look if there is a carry
1857: compRem = roundingBehavior(
1858: integerAndFraction[0].testBit(0) ? 1 : 0,
1859: integerAndFraction[1].signum() * (5 + compRem), mc
1860: .getRoundingMode());
1861: if (compRem != 0) {
1862: integerAndFraction[0] = integerAndFraction[0]
1863: .add(BigInteger.valueOf(compRem));
1864: }
1865: tempBD = new BigDecimal(integerAndFraction[0]);
1866: // If after to add the increment the precision changed, we normalize the size
1867: if (tempBD.precision() > mcPrecision) {
1868: integerAndFraction[0] = integerAndFraction[0]
1869: .divide(BigInteger.TEN);
1870: newScale--;
1871: }
1872: }
1873: // To update all internal fields
1874: scale = toIntScale(newScale);
1875: precision = mcPrecision;
1876: setUnscaledValue(integerAndFraction[0]);
1877: }
1878:
1879: private static int longCompareTo(long value1, long value2) {
1880: return value1 > value2 ? 1 : (value1 < value2 ? -1 : 0);
1881: }
1882:
1883: /**
1884: * This method implements an efficient rounding for numbers which unscaled
1885: * value fits in the type <code>long</code>.
1886: * @param mc the context to use.
1887: * @param discardedPrecision the number of decimal digits that are discarded.
1888: * @see #round(MathContext).
1889: */
1890: private void smallRound(MathContext mc, int discardedPrecision) {
1891: long sizeOfFraction = LONG_TEN_POW[discardedPrecision];
1892: long newScale = (long) scale - discardedPrecision;
1893: long unscaledVal = smallValue;
1894: // Getting the integer part and the discarded fraction
1895: long integer = unscaledVal / sizeOfFraction;
1896: long fraction = unscaledVal % sizeOfFraction;
1897: int compRem;
1898: // If the discarded fraction is non-zero perform rounding
1899: if (fraction != 0) {
1900: // To check if the discarded fraction >= 0.5
1901: compRem = longCompareTo(Math.abs(fraction) << 1,
1902: sizeOfFraction);
1903: // To look if there is a carry
1904: integer += roundingBehavior(((int) integer) & 1, Long
1905: .signum(fraction)
1906: * (5 + compRem), mc.getRoundingMode());
1907: // If after to add the increment the precision changed, we normalize the size
1908: if (Math.log10(Math.abs(integer)) >= mc.getPrecision()) {
1909: integer /= 10;
1910: newScale--;
1911: }
1912: }
1913: // To update all internal fields
1914: scale = toIntScale(newScale);
1915: precision = mc.getPrecision();
1916: smallValue = integer;
1917: bitLength = bitLength(integer);
1918: intVal = null;
1919: }
1920:
1921: /**
1922: * Return an increment that can be -1,0 or 1, depending of <code>roundingMode</code>.
1923: * @param parityBit can be 0 or 1, it's only used in the case <code>HALF_EVEN</code>.
1924: * @param fraction the mantisa to be analyzed.
1925: * @param roundingMode the type of rounding.
1926: * @return the carry propagated after rounding.
1927: */
1928: private static int roundingBehavior(int parityBit, int fraction,
1929: RoundingMode roundingMode) {
1930: int increment = 0; // the carry after rounding
1931:
1932: switch (roundingMode) {
1933: case UNNECESSARY:
1934: if (fraction != 0) {
1935: // math.08=Rounding necessary
1936: throw new ArithmeticException(Messages
1937: .getString("math.08")); //$NON-NLS-1$
1938: }
1939: break;
1940: case UP:
1941: increment = Integer.signum(fraction);
1942: break;
1943: case DOWN:
1944: break;
1945: case CEILING:
1946: increment = Math.max(Integer.signum(fraction), 0);
1947: break;
1948: case FLOOR:
1949: increment = Math.min(Integer.signum(fraction), 0);
1950: break;
1951: case HALF_UP:
1952: if (Math.abs(fraction) >= 5) {
1953: increment = Integer.signum(fraction);
1954: }
1955: break;
1956: case HALF_DOWN:
1957: if (Math.abs(fraction) > 5) {
1958: increment = Integer.signum(fraction);
1959: }
1960: break;
1961: case HALF_EVEN:
1962: if (Math.abs(fraction) + parityBit > 5) {
1963: increment = Integer.signum(fraction);
1964: }
1965: break;
1966: }
1967: return increment;
1968: }
1969:
1970: /**
1971: * If <code>intVal</code> has a fractional part throws an exception,
1972: * otherwise it counts the number of bits of value and checks if it's out
1973: * of the range of the primitive type. If the number fits in the primitive
1974: * type returns this number as <code>long</code>, otherwise throws an
1975: * exception.
1976: *
1977: * @param bitLengthOfType number of bits of the type whose value will be
1978: * calculated exactly.
1979: * @return the exact value of the integer part of <code>BigDecimal</code>
1980: * when is possible.
1981: * @throws <code>ArithmeticException</code> when rounding is necessary or
1982: * the number don't fit in the primitive type.
1983: */
1984: private long valueExact(int bitLengthOfType) {
1985: BigInteger bigInteger = toBigIntegerExact();
1986:
1987: if (bigInteger.bitLength() < bitLengthOfType) {
1988: // It fits in the primitive type
1989: return bigInteger.longValue();
1990: }
1991: // math.08=Rounding necessary
1992: throw new ArithmeticException(Messages.getString("math.08")); //$NON-NLS-1$
1993: }
1994:
1995: /**
1996: * If the precision already was calculated it returns that value, otherwise
1997: * it calculates a very good approximation efficiently . Note that this
1998: * value will be <code>precision()</code> or <code>precision()-1</code>
1999: * in the worst case.
2000: * @return an approximation of <code>precision()</code> value
2001: */
2002: private int aproxPrecision() {
2003: return ((precision > 0) ? precision
2004: : (int) ((this .bitLength - 1) * LOG10_2)) + 1;
2005: }
2006:
2007: /**
2008: * It tests if a scale of type <code>long</code> fits in 32 bits.
2009: * It returns the same scale being casted to <code>int</code> type when
2010: * is possible, otherwise throws an exception.
2011: * @param longScale a 64 bit scale.
2012: * @return a 32 bit scale when is possible.
2013: * @throws <code>ArithmeticException</code> when <code>scale</code>
2014: * doesn't fit in <code>int</code> type.
2015: * @see #scale
2016: */
2017: private static int toIntScale(long longScale) {
2018: if (longScale < Integer.MIN_VALUE) {
2019: // math.09=Overflow
2020: throw new ArithmeticException(Messages.getString("math.09")); //$NON-NLS-1$
2021: } else if (longScale > Integer.MAX_VALUE) {
2022: // math.0A=Underflow
2023: throw new ArithmeticException(Messages.getString("math.0A")); //$NON-NLS-1$
2024: } else {
2025: return (int) longScale;
2026: }
2027: }
2028:
2029: /**
2030: * It returns the value 0 with the most approximated scale of type
2031: * <code>int</code>. if <code>longScale > Integer.MAX_VALUE</code>
2032: * the scale will be <code>Integer.MAX_VALUE</code>; if
2033: * <code>longScale < Integer.MIN_VALUE</code> the scale will be
2034: * <code>Integer.MIN_VALUE</code>; otherwise <code>longScale</code> is
2035: * casted to the type <code>int</code>.
2036: * @param longScale the scale to which the value 0 will be scaled.
2037: * @return the value 0 scaled by the closer scale of type <code>int</code>.
2038: * @see #scale
2039: */
2040: private static BigDecimal zeroScaledBy(long longScale) {
2041: if (longScale == (int) longScale) {
2042: return valueOf(0, (int) longScale);
2043: }
2044: if (longScale >= 0) {
2045: return new BigDecimal(0, Integer.MAX_VALUE);
2046: }
2047: return new BigDecimal(0, Integer.MIN_VALUE);
2048: }
2049:
2050: /** @ar.org.fitc.spec_ref */
2051: private void readObject(ObjectInputStream in) throws IOException,
2052: ClassNotFoundException {
2053: in.defaultReadObject();
2054:
2055: this .bitLength = intVal.bitLength();
2056: if (this .bitLength < 64) {
2057: this .smallValue = intVal.longValue();
2058: }
2059: }
2060:
2061: private void writeObject(ObjectOutputStream out) throws IOException {
2062: getUnscaledValue();
2063: out.defaultWriteObject();
2064: }
2065:
2066: private BigInteger getUnscaledValue() {
2067: if (intVal == null) {
2068: intVal = BigInteger.valueOf(smallValue);
2069: }
2070: return intVal;
2071: }
2072:
2073: private void setUnscaledValue(BigInteger unscaledValue) {
2074: this .intVal = unscaledValue;
2075: this .bitLength = unscaledValue.bitLength();
2076: if (this .bitLength < 64) {
2077: this .smallValue = unscaledValue.longValue();
2078: }
2079: }
2080:
2081: private static int bitLength(long smallValue) {
2082: if (smallValue < 0) {
2083: smallValue = ~smallValue;
2084: }
2085: return 64 - Long.numberOfLeadingZeros(smallValue);
2086: }
2087:
2088: private static int bitLength(int smallValue) {
2089: if (smallValue < 0) {
2090: smallValue = ~smallValue;
2091: }
2092: return 32 - Integer.numberOfLeadingZeros(smallValue);
2093: }
2094:
2095: }
|