public int compareTo(BigDecimal val) { int thisSign = signum(); int valueSign = val.signum(); if( thisSign == valueSign) { if(this._scale == val._scale && this._bitLength<64 && val._bitLength<64 ) { return (smallValue < val.smallValue) ? -1 : (smallValue > val.smallValue) ? 1 : 0; } long diffScale = (long)this._scale - val._scale; int diffPrecision = this.aproxPrecision() - val.aproxPrecision(); if (diffPrecision > diffScale + 1) { return thisSign; } else if (diffPrecision < diffScale - 1) { return -thisSign; } else {// thisSign == val.signum() and diffPrecision is aprox. diffScale BigInteger thisUnscaled = this.getUnscaledValue(); BigInteger valUnscaled = val.getUnscaledValue(); // If any of both precision is bigger, append zeros to the shorter one if (diffScale < 0) { thisUnscaled = thisUnscaled.multiply(Multiplication.powerOf10(-diffScale)); } else if (diffScale > 0) { valUnscaled = valUnscaled.multiply(Multiplication.powerOf10(diffScale)); } return thisUnscaled.compareTo(valUnscaled); } } else if (thisSign < valueSign) { return -1; } else { return 1; } }
public BigDecimal subtract(BigDecimal subtrahend, MathContext mc) { long diffScale = subtrahend._scale - (long)this._scale; int thisSignum; BigDecimal leftOperand; // it will be only the left operand (this) BigInteger tempBI; // Some operand is zero or the precision is infinity if ((subtrahend.isZero()) || (this.isZero()) || (mc.getPrecision() == 0)) { return subtract(subtrahend).round(mc); } // Now: this != 0 and subtrahend != 0 if (subtrahend.aproxPrecision() < diffScale - 1) { // Cases where it is unnecessary to subtract two numbers with very different scales if (mc.getPrecision() < this.aproxPrecision()) { thisSignum = this.signum(); if (thisSignum != subtrahend.signum()) { tempBI = Multiplication.multiplyByPositiveInt(this.getUnscaledValue(), 10) .add(BigInteger.valueOf(thisSignum)); } else { tempBI = this.getUnscaledValue().subtract(BigInteger.valueOf(thisSignum)); tempBI = Multiplication.multiplyByPositiveInt(tempBI, 10) .add(BigInteger.valueOf(thisSignum * 9)); } // Rounding the improved subtracting leftOperand = new BigDecimal(tempBI, this._scale + 1); return leftOperand.round(mc); } } // No optimization is done return subtract(subtrahend).round(mc); }