質問

私の小さなプロジェクトでは、Math.Pow(7777.66、5555.44)のようなことをする必要があります。私はいくつかの解決策に出会いました:

  • ダブルを使用しますが、数字が大きすぎます
  • bigdecimal.powを使用しますが、分数のサポートはありません
  • x^(a+b)= x^a*x^b式を使用します(bは2番目の数字の残りの部分です)が、再びdoubleに変換するため、Big XまたはBig Aのサポートはありません
  • ある種のテイラーシリーズアルゴリズムなどを使用してください - 私は数学があまり得意ではないので、解決策が見つからない場合、これは私の最後のオプションです((a+b)^(cの式」 +d))。

誰かが図書館や簡単な解決策を知っていますか?私は多くの人々が同じ問題に対処することを考えました...

PS私はAPFLOATと呼ばれるいくつかのライブラリを見つけました。

役に立ちましたか?

解決

1.7976931348623157E308(double.max_value)に基づく引数のソリューションですが、数百万桁で結果をサポートしています。

DoubleはMAX_Valueまでの数値をサポートしているため(たとえば、100!は次のようになります:9.332621544394415E157)、BigDecimal.DoubleValue()を使用するのに問題はありません。ただし、MAX_Valueよりも結果が大きい場合は無限になるため、Math.Pow(Double、Double)だけを行うべきではありません。したがって、式x^(a+b)= x^a*x^bを使用して、計算を2つのパワー(bigdecimal.powを使用して)を2つのパワーに分離します。捕虜、次に乗算します。 xはダブルにコピーされます - max_valueよりも大きくないことを確認します。このようにして、次のことを行うことができます(私のプライベート定数などを無視してください)。

    int signOf2 = n2.signum();
    try {
        // Perform X^(A+B)=X^A*X^B (B = remainder)
        double dn1 = n1.doubleValue();
        // Compare the same row of digits according to context
        if (!CalculatorUtils.isEqual(n1, dn1))
            throw new Exception(); // Cannot convert n1 to double
        n2 = n2.multiply(new BigDecimal(signOf2)); // n2 is now positive
        BigDecimal remainderOf2 = n2.remainder(BigDecimal.ONE);
        BigDecimal n2IntPart = n2.subtract(remainderOf2);
        // Calculate big part of the power using context -
        // bigger range and performance but lower accuracy
        BigDecimal intPow = n1.pow(n2IntPart.intValueExact(),
                CalculatorConstants.DEFAULT_CONTEXT);
        BigDecimal doublePow =
            new BigDecimal(Math.pow(dn1, remainderOf2.doubleValue()));
        result = intPow.multiply(doublePow);
    } catch (Exception e) {
        if (e instanceof CalculatorException)
            throw (CalculatorException) e;
        throw new CalculatorException(
            CalculatorConstants.Errors.UNSUPPORTED_NUMBER_ +
                "power!");
    }
    // Fix negative power
    if (signOf2 == -1)
        result = BigDecimal.ONE.divide(result, CalculatorConstants.BIG_SCALE,
                RoundingMode.HALF_UP);

結果の例:

50!^10! = 12.50911317862076252364259*10^233996181

50!^0.06 = 7395.788659356498101260513

他のヒント

Exponents = Logarithms。

を見てみましょう BigDecimalの対数

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top