Calculating the nth Root in Java – 在Java中计算n次方根

最后修改: 2018年 10月 6日

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.

在Java中使用pow()试图找到n-th root,在某些情况下是不准确的。原因是,双数在途中可能会失去精度。因此,我们可能需要对结果进行抛光,以处理这些情况。

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.