RFR: 8355992: Add unsignedMultiplyExact and *powExact methods to Math and StrictMath [v2]
fabioromano1
duke at openjdk.org
Fri May 2 16:10:51 UTC 2025
On Fri, 2 May 2025 15:12:01 GMT, Raffaello Giulietti <rgiulietti at openjdk.org> wrote:
>> Add `powExact()` and `unsignedPowExact()` methods that operate on integer values arguments.
>> Further, add `unsignedMultiplyExact` methods as well.
>
> 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.
Some easy optimizations for special cases.
src/java.base/share/classes/java/lang/Math.java line 3494:
> 3492: return 1;
> 3493: }
> 3494: if (x == 0 || x == 1) {
Suggestion:
if (x == 0 || x == 1 || n == 1) {
src/java.base/share/classes/java/lang/Math.java line 3500:
> 3498: return (n & 0b1) == 0 ? 1 : -1;
> 3499: }
> 3500:
Suggestion:
if (x == 2) {
if (n >= Integer.SIZE - 1)
throw new ArithmeticException("integer overflow");
return 1 << n;
}
if (x == -2) {
if (n >= Integer.SIZE)
throw new ArithmeticException("integer overflow");
// if n == Integer.SIZE - 1, result is correct
return (n & 0b1) == 0 ? 1 << n : -(1 << n);
}
if ((java.math.BigInteger.bitLengthForInt(Math.abs(x)) - 1L) * n + 1L > Integer.SIZE) {
throw new ArithmeticException("integer overflow");
}
With also a check for the condition `java.math.BigInteger.bitLengthForInt(Math.abs(x)) * n < Integer.SIZE`, when it is true the path could be led to a loop that skips the checks.
src/java.base/share/classes/java/lang/Math.java line 3532:
> 3530: return 1;
> 3531: }
> 3532: if (x == 0 || x == 1) {
Suggestion:
if (x == 0 || x == 1 || n == 1) {
src/java.base/share/classes/java/lang/Math.java line 3535:
> 3533: return x;
> 3534: }
> 3535:
Suggestion:
if (x == 2) {
if (n >= Integer.SIZE)
throw new ArithmeticException("unsigned integer overflow");
return 1 << n;
}
if ((java.math.BigInteger.bitLengthForInt(x) - 1L) * n + 1L > Integer.SIZE) {
throw new ArithmeticException("unsigned integer overflow");
}
With also a check for the condition `java.math.BigInteger.bitLengthForInt(x) * n <= Integer.SIZE`, when it is true the path could be led to a loop that skips the checks.
src/java.base/share/classes/java/lang/Math.java line 3567:
> 3565: return 1;
> 3566: }
> 3567: if (x == 0 || x == 1) {
Suggestion:
if (x == 0 || x == 1 || n == 1) {
src/java.base/share/classes/java/lang/Math.java line 3573:
> 3571: return (n & 0b1) != 0 ? -1 : 1;
> 3572: }
> 3573:
Suggestion:
if (x == 2) {
if (n >= Long.SIZE - 1)
throw new ArithmeticException("long overflow");
return 1L << n;
}
if (x == -2) {
if (n >= Long.SIZE)
throw new ArithmeticException("long overflow");
// if n == Long.SIZE - 1, result is correct
return (n & 0b1) == 0 ? 1L << n : -(1L << n);
}
if ((java.math.BigInteger.bitLengthForLong(Math.abs(x)) - 1L) * n + 1L > Long.SIZE) {
throw new ArithmeticException("long overflow");
}
With also a check for the condition `java.math.BigInteger.bitLengthForLong(Math.abs(x)) * n < Long.SIZE`, when it is true the path could be led to a loop that skips the checks.
src/java.base/share/classes/java/lang/Math.java line 3610:
> 3608: * very small when |x| > 1, but not necessarily when |x| <= 1.
> 3609: */
> 3610: if (x == 0 || x == 1) {
Suggestion:
if (x == 0 || x == 1 || n == 1) {
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.
-------------
PR Review: https://git.openjdk.org/jdk/pull/25003#pullrequestreview-2812357251
PR Review Comment: https://git.openjdk.org/jdk/pull/25003#discussion_r2071832231
PR Review Comment: https://git.openjdk.org/jdk/pull/25003#discussion_r2071832373
PR Review Comment: https://git.openjdk.org/jdk/pull/25003#discussion_r2071833435
PR Review Comment: https://git.openjdk.org/jdk/pull/25003#discussion_r2071833501
PR Review Comment: https://git.openjdk.org/jdk/pull/25003#discussion_r2071838381
PR Review Comment: https://git.openjdk.org/jdk/pull/25003#discussion_r2071833854
PR Review Comment: https://git.openjdk.org/jdk/pull/25003#discussion_r2071816617
PR Review Comment: https://git.openjdk.org/jdk/pull/25003#discussion_r2071837334
More information about the core-libs-dev
mailing list