The accepted solution is wrong most of the time (66%), though the error is bounded (it can be smaller than the exact result by at most 2 and it can never be bigger). This comes from
- ignoring the
x_lo * y_lo
product
- first shifting and then adding
x_hi * y_lo
and x_lo * y_hi
My solution seems to always work for non-negative operands.
final long x_hi = x >>> 32;
final long y_hi = y >>> 32;
final long x_lo = x & 0xFFFFFFFFL;
final long y_lo = y & 0xFFFFFFFFL;
long result = x_lo * y_lo;
result >>>= 32;
result += x_hi * y_lo + x_lo * y_hi;
result >>>= 32;
result += x_hi * y_hi;
Tested on a billion random operands. There should be a special test for corner cases and some analysis.
Dealing with negative operands would be more complicated as it'd prohibit using the unsigned shift and force us to handle intermediate result overflow.
In case speed doesn't matter much (and it rarely does), I'd go for
BigInteger.valueOf(x).multiply(BigInteger.valueOf(y))
.shiftRight(64).longValue();
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…