Esempio n. 1
0
        private static BigDecimal divideBigIntegers(BigInteger scaledDividend, BigInteger scaledDivisor, int scale, RoundingMode roundingMode)
        {
            BigInteger[] quotAndRem = scaledDividend.divideAndRemainder(scaledDivisor);  // quotient and remainder

            // If after division there is a remainder...
            BigInteger quotient = quotAndRem[0];
            BigInteger remainder = quotAndRem[1];
            if (remainder.signum() == 0) {
                return new BigDecimal(quotient, scale);
            }
            int sign = scaledDividend.signum() * scaledDivisor.signum();
            int compRem;                                      // 'compare to remainder'
            if(scaledDivisor.bitLength() < 63) { // 63 in order to avoid out of long after <<1
                long rem = remainder.longValue();
                long divisor = scaledDivisor.longValue();
                compRem = longCompareTo(Math.Abs(rem) << 1,Math.Abs(divisor));
                // To look if there is a carry
                compRem = roundingBehavior(quotient.testBit(0) ? 1 : 0,
                                           sign * (5 + compRem), roundingMode);

            } else {
                // Checking if:  remainder * 2 >= scaledDivisor
                compRem = remainder.abs().shiftLeftOneBit().compareTo(scaledDivisor.abs());
                compRem = roundingBehavior(quotient.testBit(0) ? 1 : 0,
                                           sign * (5 + compRem), roundingMode);
            }
            if (compRem != 0) {
                if(quotient.bitLength() < 63) {
                    return valueOf(quotient.longValue() + compRem,scale);
                }
                quotient = quotient.add(BigInteger.valueOf(compRem));
                return new BigDecimal(quotient, scale);
            }
            // Constructing the result with the appropriate unscaled value
            return new BigDecimal(quotient, scale);
        }