1概要


pow()

を使用してJavaでn番目のルートを見つけようとするのは不正確な場合があります。その理由は、

Math.pow(double

a、

double b)

が倍精度数を使用し、途中で精度を失うからです。


2 N番目の根を正しく計算する

2


. 1. 実装


上記の問題に対する解決策は、ほとんど数学的な回避策です。それは、できる限り簡単です。

数値xのn乗根は

1/n


のべき乗で数値xと等しいことはよく知られています。

また、


x ^(1/n)= e ^(lnx/n)


であることが証明されました。ここで、

lnx

は自然対数です。

これに基づいたソリューションをJavaで実装しましょう。

まず最初に、

NthRootCalcurator

クラスです。

public class NthRootCalculator {
    public Double calculate(Double base, Double n) {
        return Math.pow(Math.E, Math.log(base)/n);
    }
}

このクラスは、上で説明した実装をホストします。今、l

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);
    }
}

テストは私達の計算機が正しく5である125の3乗根を正しく計算することを証明します。

2


. 2. 精度についての注意


以下に、回避策が提供する精度の例を示します。最初の出力は

Math.pow

を使用する関数の出力であり、2番目の出力は次の回避策を使用しています。

The 3.0 root of 125.0 equals to 4.999999999999999.

The 3.0 root of 125.0 equals to 5.0.


3結論

上で説明した数学的な回避策はかなり良い精度で本当にうまくいきます。さらに、この回避策は、再帰的または反復的なコードを使用してn番目の根を計算する他の手法よりも効率的です。

上記のソリューションのコードはhttps://github.com/eugenp/tutorials/tree/master/core-java[GitHubに追加]を参照してください。