在我的小项目中,我需要做诸如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)的参数解决方案,但具有数百万个数字的支持结果:

由于Double支持数字到MAX_VALUE(例如,100!双看起来像这样:9.3326215444394415E157),因此使用BigDecimal.double.double.double.double.double.double.double.double.double.double.double.double.double.double.double.double.double.double.double.double.double.double.double.double.double.double.double.double.double.double.double.double.double.double.double.double.double.double.double.double()。但是您不应该只是做数学。要做(双重,double),因为如果结果大于max_value,则只会获得无穷大。因此:使用公式x^(a+b)= x^a*x^b将计算与使用bigdecimal.pow和小(第二个参数的其余部分)的两个幂分开,并使用数学分开计算。 POW,然后繁殖。 X将被复制为double-确保它不大于max_value,a将是int(最多2147483647,但bigdecimal.pow不得支持整数超过10亿美元),并且b将翻倍,始终小于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

其他提示

指数=对数。

看一眼 巨大的对数

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top