RFR: 8355992: Add unsignedMultiplyExact and *powExact methods to Math and StrictMath [v2]

Raffaello Giulietti rgiulietti at openjdk.org
Fri May 2 16:47:47 UTC 2025


On Fri, 2 May 2025 16:06:42 GMT, fabioromano1 <duke at openjdk.org> wrote:

>> Raffaello Giulietti has updated the pull request incrementally with one additional commit since the last revision:
>> 
>>   Clearer and more complete spec of the *pow* methods.
>
> src/java.base/share/classes/java/lang/Math.java line 3613:
> 
>> 3611:             return x;
>> 3612:         }
>> 3613: 
> 
> Suggestion:
> 
> 
>         if (x == 2) {
>             if (n >= Long.SIZE)
>                 throw new ArithmeticException("unsigned long overflow");
>             return 1L << n;
>         }
> 
>        if ((java.math.BigInteger.bitLengthForLong(x) - 1L) * n + 1L > Long.SIZE) {
>            throw new ArithmeticException("unsigned long overflow");
>        }
> 
> With also a check for the condition `java.math.BigInteger.bitLengthForLong(x) * n <= Long.SIZE`, when it is true the path could be led to a loop that skips the checks.

I don't think there's a quick, _precise_ pre-check that would ensure that the loop can just use simple, unchecked `*` multiplications.

Consider `unsignedPowExact(3L, 40)`, which does not overflow, versus `unsignedPowExact(3L, 41)`, which does.
How would you pre-check these two cases using integer arithmetic?

IMO, you still need checked multiplications in the loop.

(Besides, the product in your checks can overflow, so you would have to add a guard.)

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/25003#discussion_r2071884269


More information about the core-libs-dev mailing list