I need to write a method that returns the power of only integers

I need to write a method in java to return the power of only an integer, and I want this method to return -1 or a fire exception if the number exceeds Integer.MAX_VALUE:

I tried the first and simple step:

public static int GetPower(int base, int power) { int result = 1; for(int i = 1; i<=power; i++) { result *= base; if (result < 0 ) { break; // not very acurate } } if (result < 0 ) { return -1; } return result; } 

Is the above method accurate, since after debugging I found that when the result exceeds Integer.MAX_VALUE, it will go for a negative number or is there another way to handle this?

+6
source share
7 answers

Your method will work if the base can only be a positive integer. Underutilization of your base may occur - this is a negative integer, and your power is an odd number.

An easy but not optimal way to handle this situation is to use a long data type to store the output and compare the output to see if it is between Integer.MAX_VALUE and Integer.MIN_VALUE.

 public static int GetPower(int base, int power){ long result = 1; for(int i = 1; i <= power; i++) { result *= base; if (result > Integer.MAX_VALUE || result < Integer.MIN_VALUE) { return -1; } } return result; } 
+4
source

The answers of Nitram and PythaLye work, but I don't like the idea of ​​using a different data type to check for borders. Instead, I suggest you use this simple check:

 // This basically means result * base > boundary if ((base > 0 && result > (Integer.MAX_VALUE / base)) || (base < 0 && result < (Integer.MIN_VALUE / -base)) // Negative base case { return -1; } 

Thus, the code will look like this:

 public static int GetPower(int base, int power) { int result = 1; for(int i = 1; i<=power; i++) { if ((base > 0 && result > (Integer.MAX_VALUE / base)) || (base < 0 && result < (Integer.MIN_VALUE / -base)) { return -1; } result *= base; } return result; } 
+3
source

The effect you noticed is a numerical overflow. If you add it to Integer.MAX_VALUE , you will get the result Integer.MIN_VALUE .

Now you need more space to store your value. Since you want to work in 32-bit Integer space, you need the following big thing. And that will be the 64-bit Long value. This is in any case faster compared to any use of BigDecimals .

You just need to check inside any step of the loop if your value has exceeded Integer.MAX_VALUE and canceled it if that happens.

Thus, the resulting code will be something like this:

 public static int GetPower(int base, int power) { long result = 1; for(int i = 1; i <= power; i++) { result *= base; if (result > Integer.MAX_VALUE) { return -1; } } return result; } 

In addition, I suggest you check the function input to ensure that the base is not negative.

+2
source

Since you have a simple implementation of the pow method that does not accept negative numbers or values, my suggestion would be to create the maximum allowed value, and just check that your result is less.

 public static int getPower(int base, int power) { int result = 1; int maxAllowed = Integer.MAX_VALUE / base; for(int i = 1; i<=power; i++) { result *= base; if (i!=power && result>=maxAllowed){ return -1; } } return result; } 

But overall, I highly recommend not reinventing the wheel and going with the Math.pow method

+2
source

As already mentioned, using a “larger” data type allows you to check and easily calculate, but what if there is no larger data type?

You can mathematically test if this leads to overflow:

If you are caluclating base^power , it means base^power = result - it also means power-th square of result = base - The maximum allowed result is Integer.MAX_VALUE - otherwise you have an overflow.

power-th root ANY number greater than zero will ALWAYS fall within the range ]0,number] - there is no likelihood of arithmetic overflows.

So - compare the base you are using with power-th root Integer.MAX_VALUE - base LARGER ? Then you will encounter overflow - otherwise it will stick below (or be equal to) the result of Integer.MAX_VALUE

 private static double powSafe(double base, int pow){ //this is the p-th root of the maximum integer allowed double root = Math.pow(Integer.MAX_VALUE, 1.0/pow); if (root < base){ throw new ArithmeticException("The calculation of " + base + "^" + pow + " would overflow."); }else{ return Math.pow(base, pow); } } public static void main(String[] argv) { double rootOfMaxInt = Math.pow(Integer.MAX_VALUE, 1.0/2); try{ //that should be INTEGER.MAX_VALUE, so valid. double d1 = powSafe(rootOfMaxInt, 2); System.out.println(rootOfMaxInt + "^2 = " + d1); }catch (ArithmeticException e){ System.out.println(e.getMessage()); } try{ //this should overflow cause "+1" double d2 = powSafe(rootOfMaxInt +1, 2); System.out.println("("rootOfMaxInt + "+ 1)^2 = " + d1); }catch (ArithmeticException e){ System.out.println(e.getMessage()); } double the67thRootOfMaxInt = Math.pow(Integer.MAX_VALUE, 1.0/67); try{ //and so, it continues double d3 = powSafe(the67thRootOfMaxInt, 67); System.out.println(the67thRootOfMaxInt + "^67 = " + d3); double d4 = powSafe(the67thRootOfMaxInt +1, 67); System.out.println("(" + the67thRootOfMaxInt + " + 1)^67 = " + d3); }catch (ArithmeticException e){ System.out.println(e.getMessage()); } } 

leads to

 46340.950001051984^2 = 2.147483647E9 The calculation of 46341.950001051984^2 would overflow. 1.3781057199632372^67 = 2.1474836470000062E9 The calculation of 2.378105719963237^67 would overflow. 

Note that inaccuracies appear because double does not have infinite precision, which already truncates the expression 2nd square of Integer.Max_Value , the reason Integer.MAX_VALUE odd.

+2
source

You are wrong. Try your method with parameters 1 <32 and 2.

A valid check will be something like result==result*base/base , if true, than you can multiply result and base without overflow.

0
source

Java.lang.Math already has a superbly efficient power function. I highly recommend using it to cover edge cases.

 public class GetPower { public static int getPower(int base, int power) { double result = Math.pow(base, power); // check result in range if (result > Integer.MAX_VALUE) return -1; if (result < Integer.MIN_VALUE) return -1; return (int) result; } public static void main(String[] args) { for (int base=0; base<=10; ++base) { for (int power=0; power<=10; ++power) { int result = getPower(base, power); System.out.println("getPower(" + base + ", " + power + ") = " + result); } } } } 

No need to reinvent the wheel. No need to worry about floating point inaccuracies - all int values ​​are perfectly represented as double.

0
source

Source: https://habr.com/ru/post/989409/


All Articles