Math pow is a function which calculates the power of any base number in Java. We’re going to learn how to avoid the common pitfalls around this method. java https://octoperf.com/blog/2018/03/16/java-math-pow/ OctoPerf ZI Les Paluds, 276 Avenue du Douard, 13400 Aubagne, France +334 42 84 12 59 contact@octoperf.com Development 1421 2021-01-04

# Java Math.pow Through Code Examples

OctoPerf is JMeter on steroids!

I’m sure you have already experienced odd results when calling Math.pow method. I know, I’ve been there too!

`Math.pow(double a, double b)` returns the value of `a` raised to the power of `b`.

It’s a static method on `Math` class, which means you don’t have to instantiate a `Math` instance to call it. The power of a number is the number of times the number is multiplied by itself.

## Example Code

Let’s see the following example:

 `````` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 `````` `````` package com.octoperf; import org.junit.Test; import static java.lang.Double.NEGATIVE_INFINITY; import static java.lang.Double.NaN; import static java.lang.Double.POSITIVE_INFINITY; import static org.junit.Assert.assertEquals; public class MathPowTest { private static final double DELTA = 0.001d; @Test public void simpleExample() { assertEquals(1024d, Math.pow(2d, 10d), DELTA); } } ``````

The 10th power of `2` is `1024`. The result is a `double`. Beware of casting the result to:

• an integer: it could overflow, which means the double value does not fit into the `int` value. `int` values are stored in 4 bytes (32bits) while double values are stored in 8 bytes (64Bits),
• a long: you loose the decimal value.

Great! But, what happens if we call this method with some strange `Double` values like `Double.NaN` or `Double.POSITIVE_INFINITY`? Let’s figure out!

## Corner Cases

The `java.lang.Math` class method `pow` has several corner cases detailed in the following code:

 `````` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 `````` ``````package com.octoperf; import org.junit.Test; import static java.lang.Double.NEGATIVE_INFINITY; import static java.lang.Double.NaN; import static java.lang.Double.POSITIVE_INFINITY; import static org.junit.Assert.assertEquals; public class MathPowTest { private static final double DELTA = 0.001d; @Test public void javaMathPow() { // If the second argument is positive or negative zero, then the result is 1.0. assertEquals(1, Math.pow(2, 0), DELTA); // If the second argument is 1.0, then the result is the same as the first argument. assertEquals(2d, Math.pow(2, 1), DELTA); // If the second argument is NaN, then the result is NaN. assertEquals(NaN, Math.pow(2, NaN), DELTA); // If the absolute value of the first argument is greater than 1 and the second argument is positive infinity, or // the absolute value of the first argument is less than 1 and the second argument is negative infinity, // then the result is positive infinity. assertEquals(POSITIVE_INFINITY, Math.pow(2, POSITIVE_INFINITY), DELTA); assertEquals(POSITIVE_INFINITY, Math.pow(0.5d, NEGATIVE_INFINITY), DELTA); // If the absolute value of the first argument is greater than 1 and the second argument is negative infinity, or // the absolute value of the first argument is less than 1 and the second argument is positive infinity, // then the result is positive zero. assertEquals(0d, Math.pow(2, NEGATIVE_INFINITY), DELTA); assertEquals(0d, Math.pow(0.5d, POSITIVE_INFINITY), DELTA); // If the absolute value of the first argument equals 1 and the second argument is infinite, then the result is NaN. assertEquals(NaN, Math.pow(1d, POSITIVE_INFINITY), DELTA); // If // the first argument is positive zero and the second argument is greater than zero, or // the first argument is positive infinity and the second argument is less than zero, // then the result is positive zero. assertEquals(0d, Math.pow(0d, 1d), DELTA); assertEquals(0d, Math.pow(POSITIVE_INFINITY, -1d), DELTA); // If // the first argument is positive zero and the second argument is less than zero, or // the first argument is positive infinity and the second argument is greater than zero, // then the result is positive infinity. assertEquals(POSITIVE_INFINITY, Math.pow(0d, -1d), DELTA); assertEquals(POSITIVE_INFINITY, Math.pow(POSITIVE_INFINITY, 1d), DELTA); // If //the first argument is negative zero and the second argument is greater than zero but not a finite odd integer, or //the first argument is negative infinity and the second argument is less than zero but not a finite odd integer, //then the result is positive zero. assertEquals(0d, Math.pow(-0d, 0.5d), DELTA); assertEquals(0d, Math.pow(NEGATIVE_INFINITY, -1.5d), DELTA); // If // the first argument is negative zero and the second argument is a positive finite odd integer, or // the first argument is negative infinity and the second argument is a negative finite odd integer, // then the result is negative zero. assertEquals(0d, Math.pow(-0d, 1d), DELTA); assertEquals(0d, Math.pow(NEGATIVE_INFINITY, -1d), DELTA); // If // the first argument is negative zero and the second argument is less than zero but not a finite odd integer, or // the first argument is negative infinity and the second argument is greater than zero but not a finite odd integer, // then the result is positive infinity. assertEquals(POSITIVE_INFINITY, Math.pow(-0d, -2d), DELTA); assertEquals(POSITIVE_INFINITY, Math.pow(NEGATIVE_INFINITY, 2d), DELTA); // If // the first argument is negative zero and the second argument is a negative finite odd integer, or // the first argument is negative infinity and the second argument is a positive finite odd integer, // then the result is negative infinity. assertEquals(NEGATIVE_INFINITY, Math.pow(-0d, -1d), DELTA); assertEquals(NEGATIVE_INFINITY, Math.pow(NEGATIVE_INFINITY, 1d), DELTA); // If the first argument is finite and less than zero // if the second argument is a finite even integer, the result is equal to the result of raising // the absolute value of the first argument to the power of the second argument // if the second argument is a finite odd integer, the result is equal to the negative of the // result of raising the absolute value of the first argument to the power of the second argument // if the second argument is finite and not an integer, then the result is NaN. assertEquals(1d, Math.pow(-1d, 2), DELTA); assertEquals(-1d, Math.pow(-1d, 3), DELTA); assertEquals(NaN, Math.pow(-1d, 2.5d), DELTA); // If both arguments are integers, then the result is exactly equal to the mathematical // result of raising the first argument to the power of the second argument if that result // can in fact be represented exactly as a double value. assertEquals(1024d, Math.pow(2d, 10d), DELTA); } } ``````

One should be careful when calling the Math.pow function as it has several edge cases which can return unexpected results. All the corner cases have been detailed in the code above.

But wait! We’re not finished… There is another common pitfall!

## Xor Operator Is Not Pow

Usually, when you write the power of a number you use the following syntax:

 ``````1 2 3 4 5 `````` ``````Using Math symbols: 2^5 = 2x2x2x2x2 = 32 Using Java Programming Language: Math.pow(2, 5) ``````

In Java, The result with the `^` operator is quite different as it’s the xor operator:

 `````` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 `````` `````` package com.octoperf; import org.junit.Test; import static java.lang.Double.NEGATIVE_INFINITY; import static java.lang.Double.NaN; import static java.lang.Double.POSITIVE_INFINITY; import static org.junit.Assert.assertEquals; public class MathPowTest { private static final double DELTA = 0.001d; @Test public void xorOperator() { assertEquals(32d, Math.pow(2d, 5d), DELTA); assertEquals(7d, 2 ^ 5, DELTA); } } ``````

As seen above, the results are totally different. Never use the Xor Operator to compute the power of a number.

## Exceeding Precision

One common error is the result of the power can exceed the capacity of the type it’s being casted to:

 `````` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 `````` `````` package com.octoperf; import org.junit.Test; import static java.lang.Double.NEGATIVE_INFINITY; import static java.lang.Double.NaN; import static java.lang.Double.POSITIVE_INFINITY; import static org.junit.Assert.assertEquals; public class MathPowTest { private static final double DELTA = 0.001d; @Test public void exceedingPrecision() { assertEquals(5.118589301409076E16d, Math.pow(13d, 15d), DELTA); assertEquals(51185893014090760L, (long) Math.pow(13d, 15d)); } } ``````

The correct value of `13^15` is `51185893014090757`, greater than the result returned by `Math.pow` by 15. The Math.pow method performs an approximation of the result. To get the correct result use the following code:

 ``````1 2 3 4 5 `````` ``````long b = 1; for (int i = 0; i < 15; i++) { b = b * 13; } System.out.println(b); ``````

The output is the expected result `51185893014090757L`. As a rule of thumb, the `Math.pow` method usage should be avoided when the exponent is an integer. First, the result is an approximation, and second it is more costly to compute. (although Math.pow performance is usually not a problem)

## Conclusion

Remember dealing with floating numbers in Java can be slippery. The decimal precision is limited and downcasting results can exceed the target type precision. Tags:
Share:
Be the first to comment
Thank you

Your comment has been submitted and will be published once it has been approved.

OOPS!

Want to become a super load tester?

# Related posts

Development

## Spring Annotations Demystified Development

## Spring Boot + Hazelcast Tutorial Development

## Java - 10+ Amazing Ways to Write to File Development

## Java Arrays Development

## Java ArrayList Development 