Search code examples
javaoptimizationbit-manipulationmultiplicationdivision

What's the fastest way in Java to multiply or divide with 1.6?


I want to multiply or divide big numbers (BigIntegers) with 1.6.

Currently I'm using:

Division:

BigDecimal dez = new BigDecimal("1.6");

BigDecimal bigd = new BigDecimal(big);

return bigd.divide(dez,10000, RoundingMode.FLOOR).toBigInteger();

Multiplication:

BigDecimal dez = new BigDecimal("1.6");

BigDecimal bigd = new BigDecimal(big);

return bigd.multiply(dez).toBigInteger()

Usually my numbers have 1000 <= x <= 10000 Bytes. Caching doesn't help numbers are not repeating.

Exists there a bithack to do this faster?


Solution

  • For dividing by 1.6, absolutely there's a bit hack. Mathematically, x ÷ 1.6 = x ÷ 2 + x ÷ 8

    So you can write this as

    myBigInteger.shiftRight(1).add(myBigInteger.shiftRight(3))
    

    There is no similar hack for multiplying by 1.6.

    You will have to worry about rounding errors, of course, as bits disappear off the right hand end of the number. You'll have to think about what to do with these.

    In particular, this expression is "off by one" if the last three bits of the original number are 101 or 111. So a better expression would be

    myBigInteger.shiftRight(1).add(myBigInteger.shiftRight(3)) + (myBigInteger.testBit(0) && myBigInteger.testBit(2) ? 1 : 0)