Java 计算指数增长序列中的值之和

Java 计算指数增长序列中的值之和,java,bigdecimal,exponential,Java,Bigdecimal,Exponential,(见下面的解决方案) (潜伏者出现) 我使用BigDecimal/BigInteger类来处理非常大的数字 我有一个计算复合增长序列的公式 对于每个n,值=初始*(coef^n) 我试图找到一种快速的方法来计算n0和n1之间的值子集的和 例如,n0=4,n1=6 返回:首字母*(系数^4)+首字母*(系数^5)+首字母*(系数^6) 我不太懂数学,但也许有一种公式化的表达方式 我基本上是把所有的值加起来,通过提高系数将其中的一些值聚集成10的幂 据我所知,这个函数是准确的。我可以为返回一个值 n

(见下面的解决方案)

(潜伏者出现)

我使用BigDecimal/BigInteger类来处理非常大的数字

我有一个计算复合增长序列的公式

对于每个n,值=初始*(coef^n)

我试图找到一种快速的方法来计算n0和n1之间的值子集的和

例如,n0=4,n1=6

返回:首字母*(系数^4)+首字母*(系数^5)+首字母*(系数^6)

我不太懂数学,但也许有一种公式化的表达方式

我基本上是把所有的值加起来,通过提高系数将其中的一些值聚集成10的幂

据我所知,这个函数是准确的。我可以为返回一个值

n0=1,n1=50000,初始值=100,coef=1.05英寸,在一秒钟内

虽然我可能永远不会将该函数用于大于~20000的值,但如果有更有效的方法来实现这一点,那就太好了

public static final BigDecimal sum(int n0, int n1, BigDecimal initial, BigDecimal coef) {
    BigDecimal sum = BigDecimal.ZERO;

    int short_cut = 1000000000;

    //Loop for each power of 10
    while (short_cut >= 10) {
        //Check the range of n is greater than the power of 10
        if (n1 - n0 >= short_cut) {
            //Calculate the coefficient * the power of 10
            BigDecimal xCoef = coef.pow(short_cut);

            //Add the first sum of values for n by re-calling the function for n0 to n0 + shortcut - 1
            BigDecimal add = sum(n0, n0 + short_cut - 1, initial, coef);
            sum = sum.add(add);

            //Move n forward by the power of 10
            n0 += short_cut;

            while (n1 - n0 >= short_cut) {
                //While the range is still less than the current power of 10
                //Continue to add the next sum multiplied by the coefficient
                add = add.multiply(xCoef);
                sum = sum.add(add);
                //Move n forward
                n0 += short_cut;
            }

        }
        //Move to the next smallest power of 10
        short_cut /= 10;
    }

    //Finish adding where n is smaller than 10
    for (; n0 <= n1; n0++)
        sum = sum.add(initial.multiply(coef.pow(n0)));
    return sum;
}
(首字母*coef^n0-coef^n1+1)/1-coef


谢谢维基百科。

我将写一些算法思想

首先,让我们简化您的公式:

所以你应该计算:S=a*(c^n0)+a*(c^(n0+1))+…+a*(c^n1) 其中初始值=a系数=c

设S(n)是下列和的函数: S(n)=a+a*c+a*(c^2)+…+a*(c^n)

我们将得到S=S(n1)-S(n0-1)

另一方面,S(n)是a的和,因此S(n)=a*(1-c^n)/(1-c)

所以我们将得到S=S(n1)-S(n0-1)=a*(1-c^n1)/(1-c)-a*(1-c^(n0-1))/(1-c)=a*(c^(n0-1)-c^n1)/(1-c)

所以现在我们必须处理计算c^n指数(当然BigDecimal类有pow方法,我们这样做只是为了能够计算算法的复杂性)。以下算法具有O(log(n))复杂性:

function exp(c,n){
    // throw exception when n is not an natural number or 0
    if(n == 0){
        return 1;
    }
    m = exp(c, floor(n/2));
    if (n % 2 == 0){
        return m*m;
    } else{
        return m*m*c;
    }
}

因此,如果我们考虑到代数运算具有O(1)复杂性这一事实,我们可以得出结论,求和可以用O(log(n))复杂性来计算

你也许应该问一下这个关于数学的问题。SE@DanzaBarr当我输入答案时,您已经编辑了问题并添加了解决方案:)
function exp(c,n){
    // throw exception when n is not an natural number or 0
    if(n == 0){
        return 1;
    }
    m = exp(c, floor(n/2));
    if (n % 2 == 0){
        return m*m;
    } else{
        return m*m*c;
    }
}