RFR: 8355992: Add unsignedMultiplyExact and *powExact methods to Math and StrictMath [v2]
Raffaello Giulietti
rgiulietti at openjdk.org
Fri May 2 17:52:44 UTC 2025
On Fri, 2 May 2025 17:30:55 GMT, fabioromano1 <duke at openjdk.org> wrote:
>> Again, I don't think that `n == 1` is a frequent case which would make any practical difference.
>>
>> As for the `bitLength` check, the product might overflow.
>> Further, `bitLength` might not be that cheap.
>> Finally, the test would just help to _fail_ faster at the expense of making the successful runs slightly slower.
>
>> As for the `bitLength` check, the product might overflow. Further, `bitLength` might not be that cheap.
>
> The current implementations of `bitLength()` call `numberOfLeadingZeros()`, which are:
>
> public static int numberOfLeadingZeros(long i) {
> int x = (int)(i >>> 32);
> return x == 0 ? 32 + Integer.numberOfLeadingZeros((int)i)
> : Integer.numberOfLeadingZeros(x);
> }
>
> public static int numberOfLeadingZeros(int i) {
> // HD, Count leading 0's
> if (i <= 0)
> return i == 0 ? 32 : 0;
> int n = 31;
> if (i >= 1 << 16) { n -= 16; i >>>= 16; }
> if (i >= 1 << 8) { n -= 8; i >>>= 8; }
> if (i >= 1 << 4) { n -= 4; i >>>= 4; }
> if (i >= 1 << 2) { n -= 2; i >>>= 2; }
> return n - (i >>> 1);
> }
Yes, I'm familiar with both this Java code and the intrinsic code.
Compare this with the much simpler proposed code.
The checked multiplication `unsignedMultiplyExact` apparently performs two 64x64->64 multiplications, but on some architectures it might end up in a single 64x64->128 multiplication and one check.
So the proposed code performs 6 such multiplications if the method returns + 5 ordinary multiplications in the worst case.
As a general rule, the simpler the code, the better the outcome of the optimizing compiler.
Again, to me there's no point in failing fast at the expense of the successful case.
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/25003#discussion_r2071955574
More information about the core-libs-dev
mailing list