如何在Java中对BigDecimal进行分数处理?

在我的小项目中,我需要做一些像Math.pow(7777.66,5555.44)这样的东西只有非常大的数字。 我遇到了一些解决方案:

  • 使用双倍 – 但数字太大
  • 使用BigDecimal.pow但不支持小数
  • 使用X ^(A + B)= X ^ A * X ^ B公式(B是第二个数字的余数),但是再次不支持大X或大A,因为我仍然转换为double
  • 使用某种泰勒级数算法或类似的东西 – 我不擅长数学,所以如果我找不到任何解决方案(一些库或(A + B)的公式^(C),这个是我的最后一个选项+ d))。

谁知道图书馆或简单的解决方案? 我想很多人都处理同样的问题……

ps我发现了一些名为ApFloat的图书馆声称大约是这样做的,但我得到的结果是如此近似,甚至8 ^ 2给了我60 …

1.7976931348623157E308(Double.MAX_VALUE)下的参数解决方案,但支持数字为MILLIONS的结果:

由于double支持的数字最多为MAX_VALUE(例如,100!in double看起来像这样:9.332621544394415E157),使用BigDecimal.doubleValue()没有问题。 但你不应该只做Math.pow(double,double),因为如果结果大于MAX_VALUE,你将获得无穷大。 SO:使用公式X ^(A + B)= X ^ A * X ^ B将计算分离为两个幂,使用BigDecimal.pow,使用Math将小(第二个参数的其余部分)分开。战争,然后繁殖。 X将被复制到DOUBLE – 确保它不大于MAX_VALUE,A将是INT(最大值2147483647但BigDecimal.pow不支持超过10亿的整数),B将是double,总是小于1。这样你就可以做到以下几点(忽略我的私有常量等):

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 

指数=对数。

看一下BigDecimal的Logarithm