diff --git a/src/main/java/com/thealgorithms/maths/Pow.java b/src/main/java/com/thealgorithms/maths/Pow.java index 377b37ac4569..19d40d868e17 100644 --- a/src/main/java/com/thealgorithms/maths/Pow.java +++ b/src/main/java/com/thealgorithms/maths/Pow.java @@ -16,12 +16,15 @@ private Pow() { *

* The method calculates {@code a}{@code b} by iteratively multiplying the base {@code a} with itself {@code b} times. * If the exponent {@code b} is negative, an {@code IllegalArgumentException} is thrown. + * If the exact result does not fit in a {@code long}, an {@code ArithmeticException} is thrown + * instead of silently returning a wrapped-around value. *

* - * @param a the base of the exponentiation. Must be a non-negative integer. + * @param a the base of the exponentiation. * @param b the exponent to which the base {@code a} is raised. Must be a non-negative integer. * @return the result of {@code a}{@code b} as a {@code long}. * @throws IllegalArgumentException if {@code b} is negative. + * @throws ArithmeticException if the result overflows a {@code long}. */ public static long pow(int a, int b) { if (b < 0) { @@ -29,7 +32,7 @@ public static long pow(int a, int b) { } long result = 1; for (int i = 1; i <= b; i++) { - result *= a; + result = Math.multiplyExact(result, a); } return result; } diff --git a/src/test/java/com/thealgorithms/maths/PowTest.java b/src/test/java/com/thealgorithms/maths/PowTest.java index 4309b0f10ed5..e5d5d1f2da43 100644 --- a/src/test/java/com/thealgorithms/maths/PowTest.java +++ b/src/test/java/com/thealgorithms/maths/PowTest.java @@ -33,4 +33,16 @@ void testPowHandlesZeroBase() { void testPowHandlesOneBase() { assertEquals(1, Pow.pow(1, 100)); } + + @ParameterizedTest + @CsvSource({"2, 62, 4611686018427387904", "-2, 63, -9223372036854775808", "-3, 3, -27", "-2, 4, 16", "10, 18, 1000000000000000000"}) + void testPowAtAndNearLongBounds(int base, int exponent, long expected) { + assertEquals(expected, Pow.pow(base, exponent)); + } + + @ParameterizedTest + @CsvSource({"2, 63", "2, 64", "-2, 64", "10, 19", "2147483647, 3"}) + void testPowThrowsOnOverflow(int base, int exponent) { + assertThrows(ArithmeticException.class, () -> Pow.pow(base, exponent)); + } }