JavaでBigDecimalで分数パワーを行う方法は?
-
01-10-2019 - |
質問
私の小さなプロジェクトでは、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の対数
所属していません StackOverflow