On 13 Dec 2024, at 5:22, Raffaello Giulietti wrote: > For your specific multiplication use case you might try with > > long high = Math.multiplyHigh(a, b); > long low = a * b; > if (high == 0) return low; > return "the big integer consisting of high and low"; > > It might be possible that the multiplyHigh() and * on the same operands, when > appearing adjacent to each other, get optimized to just one instruction. > And if not, they might be executed "in parallel" inside the CPU.
Here’s a relevant RFE, not yet implemented: https://bugs.openjdk.org/browse/JDK-8285871 Math.multiplyHigh and multiply on same inputs can be computed faster if their computation is shared And FWIW, a lambda-based API could be made generic in the lambda result, so that the full BigInteger (or whatever) could be returned immediately: public static <R super Long> R multiplyExact(long x, long y, BiFunction<Long,Long,R> recompute) { if (<no overflow>) return x * y; return recompute(x, y); } That lambda can also cover use cases with throwing and sigils and nulls. To work efficiently it also needs some sort of box suppression, either by reliable inlining and EA, or by handling Long as a value class. For completeness, if we get primitives over generics, then we could also spell it with lower-case “L”s: public static <R super long> R multiplyExact(long x, long y, BiFunction<long,long,R> recompute) { if (<no overflow>) return x * y; return recompute(x, y); }