14

I know that java.lang.Math provides a set of static methods to perform some operations (sum, difference, multiply, increment, decrement, negate, toInt), throwing an ArithmeticException on overflow.

Is there something similar for power?

asymmetric
  • 3,800
  • 3
  • 34
  • 52
Claudia
  • 521
  • 1
  • 5
  • 17

4 Answers4

9

No, there is nothing equivalent for pow built into Java. (The only pow methods built into Java are Math.pow, which accepts doubles and does not overflow in the same way integers do, and BigInteger.pow, which does not overflow because BigIntegers can be arbitrarily large.)

If third-party libraries are acceptable, though, Guava has e.g. IntMath.checkedPow, which does what you're looking for.

Ohad Eytan
  • 8,114
  • 1
  • 22
  • 31
Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
  • I think you should also mention `LongMath.checkedPow`. I think (though I could be wrong) it's trivial for `int` because every `int` can be represented as a double, so you just need to do `Math.pow(a, b)` and compare to `Integer.MAX_VALUE`. – Paul Boddington Nov 10 '15 at 20:51
  • @Louis If I use the `BigInteger` I can not worry about the size of the number obtained? – Claudia Nov 10 '15 at 20:55
  • 1
    @Claudia [BigInteger](https://docs.oracle.com/javase/8/docs/api/java/math/BigInteger.html): "arbitrary-precision integers ... All of the details in the Spec concerning overflow are ignored, as BigIntegers are made as large as necessary to accommodate the results of an operation." – Chris Martin Nov 10 '15 at 21:01
4

As Chirag said, integers throw exceptions when they overflow while doubles don't. Not to get too specific but, basically, doubles in memory are stored very similarly to scientific notation, in that they are some integer * 2^(some power), and thus never really overflow but multiply by such a large or small 2^(some power) that they completely lose their precision. So you can instead think of double overflow as when they completely lose their precision and are printed as either Infinity or -Infinity.

So, you will need to manually check that an overflow has occurred by checking if the resulting value is Double.POSITIVE_INFINITY or Double.NEGATIVE_INFINITY.

Here is some sample code to show what I mean:

public static void main(String[] args) throws Exception
{
    double a = Double.MAX_VALUE; // highest possible double
    double b = Double.MAX_VALUE; // highest possible double

    if (Math.pow(a, b) == Double.POSITIVE_INFINITY || Math.pow(a, b) == Double.NEGATIVE_INFINITY)
    {
        throw new ArithmeticException("Double Overflow");
    }
}
Community
  • 1
  • 1
bpgeck
  • 1,592
  • 1
  • 14
  • 32
1

If it's fine to have your own implementation, you could do something like this:

private static final int[] maxBaseForExponent = IntStream.range(0, 30)
        .map(e -> (int) Math.pow(Integer.MAX_VALUE, 1d / e)).toArray();

public static int powExact(int base, int exponent) {
    if (exponent < 0) {
        throw new ArithmeticException("Negative exponent");
    }
    if ((base < -1 || base > 1) && (exponent > 30 || base > maxBaseForExponent[exponent])
            && !(base == -2 && exponent == 31)) {
        throw new ArithmeticException("Overflow");
    }
    switch (base) {
    case -2:
        return (exponent & 1) == 0 ? 1 << exponent : -1 << exponent;
    case -1:
        return (exponent & 1) == 0 ? 1 : -1;
    case 0:
        return exponent == 0 ? 1 : 0;
    case 1:
        return 1;
    case 2:
        return 1 << exponent;
    default:
    }
    int result = 1;
    while (exponent != 0) {
        if ((exponent & 1) != 0) {
            result *= base;
        }
        exponent >>= 1;
        base *= base;
    }
    return result;
}

Took the algorithm from here, and modified it to check for overflow using an array which contains max base for each exponent from 0 to 30.

Community
  • 1
  • 1
Bubletan
  • 3,833
  • 6
  • 25
  • 33
0

Integers are only 32 bits. so max value is 2^31 -1. ( If using BigInteger.pow. It is less efficient.) So you can check manually and throw Exception if required else use Math.pow which uses double.

Chirag
  • 1,478
  • 16
  • 20
  • 3
    This is no answer. The question is whether there is such a method (I assume within the Java 8 API). – Turing85 Nov 10 '15 at 20:35
  • What I am trying to say is that we can write our own code and ofcourse there is no build in exception. thanks. – Chirag Nov 10 '15 at 20:43
  • Java is turing-complete, therefore it is assumed that you can write any algorithm within Java. – Turing85 Nov 10 '15 at 20:44