1. Overview
Trying to find the n-th root in Java using pow() is inaccurate in some cases. The reason for that is that Math.pow(double a, double b) uses double numbers, losing precision on the way.
2. Calculating the N-th Root Correctly
2.1. Implementation
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.
Also, it’s proved that x^(1/n) = e^(lnx/n) where lnx is the natural logarithm.
Let’s implement a solution based on this in Java.
First of all, we create the NthRootCalcurator class:
public class NthRootCalculator { public Double calculate(Double base, Double n) { return Math.pow(Math.E, Math.log(base)/n); } }
This class hosts the implementation that we described above. Now, let’s check how the code runs with some test runs using the JUnit testing framework:
public class NthRootCalculatorUnitTest { private NthRootCalculator nthRootCalculator = new NthRootCalculator(); @Test public void whenBaseIs125AndNIs3_thenNthRootIs5() { Double result = nthRootCalculator.calculate(125.0, 3.0); assertEquals(result, (Double) 5.0d); } }
The test proves that our calculator correctly calculates the 3rd root of 125, which is 5.
2.2. A Note On Accuracy
Below we can see an example of the accuracy that our workaround provides. The first output is the output of a function that uses Math.pow and the second is using our workaround:
The 3.0 root of 125.0 equals to 4.999999999999999.
The 3.0 root of 125.0 equals to 5.0.
3. Conclusion
The math workaround described above works really well with pretty good accuracy. In addition, it should be noted that this workaround is more efficient than other techniques that calculate the nth root using recursive or repetitive code.
The code for the solution above can be found over on GitHub.