Java Top

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> CHECK OUT THE COURSE

1. Overview

Trying to find the n-th root in Java using pow() is inaccurate in some cases. The reason for that is that double numbers can lose precision on the way. Hence we may need to polish the result to handle these cases.

2. The Problem

Suppose we want to calculate the N-th root as:

base = 125, exponent = 3

In other words, which number to the power of 3 is 125?

It's provided that the n-th root of a number x is equal with the number x in the power of 1/n. So we translate our equation to:

N-th root = Math.pow(125, 1/3)

The result is 4.999999999999999. And 4.999999999999999 to the power of 3 is not 125. So how do we fix that?

3. Calculating the N-th Root Correctly

The solution to the problem above is mostly a mathematic workaround, and it's as simple as it gets. It's well known that the n-th root of a number x is equal with the number x in the power of 1/n.

There are a few ways to leverage the equation above. First, we can use a BigDecimal and implement our version of the Newton-Raphson method. Secondly, we can round the result to the closest number and lastly, we can define a margin of error where the results will be acceptable. We'll focus on the last two approaches.

3.1. Round

We'll now use rounding to solve our problem. Let's reuse our previous example and see how we can obtain the right result:

public void whenBaseIs125AndNIs3_thenNthIs5() {
    double nth = Math.round(Math.pow(125, 1.0 / 3.0));
    assertEquals(5, nth, 0);
}

3.2. Margin of Error

This approach is very similar to be above. We just need to define an acceptable error margin, suppose 0.00001:

public void whenBaseIs625AndNIs4_thenNthIs5() {
    double nth = Math.pow(625, 1.0 / 4.0);
    assertEquals(5, nth, 0.00001);
}

The test proves that our methods correctly calculate the nth root.

4. Conclusion

As developers, we must understand the data types and their behavior. The math methods described above works really well with pretty good accuracy. You can choose the one that fits better your use case. The code for the solution above can be found over on GitHub.

Java bottom

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> CHECK OUT THE COURSE
Comments are closed on this article!