Speeding up division and remainder when numerator is a multiple of power of two

Viewed 733

I need to perform computation of the form a 2^m / b where a/b is near 1, a and b are near 2^m and m is large (greater than 1000). I need both quotient and the remainder. I can do this in Java with

BigInteger[] computeScaledRatio(BigInteger a, BigInteger b, int m) {
    return a.shiftLeft(m).divideAndRemainder(b);
}

The cost is approximately the cost of dividing a 2m-bit number by an m-bit number.

Is there a way to make this faster?

If possible, I'd like to reduce the cost to approximately the cost of dividing two m-bit numbers.

I don't care if the resulting code is more complex and/or if some external libraries are needed.

I tried the following code out of desperation. The performance, not surprisingly, is dismal.

static final double LOG2_10 = Math.log(10) / Math.log(2);
static final BigDecimal TWO = BigDecimal.valueOf(2);
BigInteger[] computeScaledRatio(BigInteger a, BigInteger b, int m) {
    int percession = (int) Math.ceil((2 * m) / LOG2_10);
    BigDecimal t = new BigDecimal(a).divide(new BigDecimal(b),
            new MathContext(percession));
    t = t.multiply(TWO.pow(m));

    BigInteger q = t.toBigInteger();
    BigInteger r = t.subtract(t.setScale(0, RoundingMode.FLOOR))
            .multiply(new BigDecimal(b)).setScale(0, RoundingMode.HALF_UP)
            .toBigInteger();
    return new BigInteger[] { q, r };
}
2 Answers
Related