簡體   English   中英

java.math.BigInteger pow(指數)問題

[英]java.math.BigInteger pow(exponent) question

我對pow(指數)方法做了一些測試。 不幸的是,我的數學技能不足以解決以下問題。

我正在使用此代碼:

BigInteger.valueOf(2).pow(var);

結果:

  • var | 時間以毫秒為單位
  • 2000000 | 11450
  • 2500000 | 12471
  • 3000000 | 22379
  • 3500000 | 32147
  • 4000000 | 46270
  • 4500000 | 31459
  • 5000000 | 49922

看到? 2,500,000指數的計算速度幾乎與2,000,000一樣快。 4,500,000的計算速度比4,000,000快得多。

這是為什么?

為了給你一些幫助,這里是BigInteger.pow(exponent)的原始實現:

 public BigInteger pow(int exponent) {
    if (exponent < 0)
        throw new ArithmeticException("Negative exponent");
    if (signum==0)
        return (exponent==0 ? ONE : this);

    // Perform exponentiation using repeated squaring trick
        int newSign = (signum<0 && (exponent&1)==1 ? -1 : 1);
    int[] baseToPow2 = this.mag;
        int[] result = {1};

    while (exponent != 0) {
        if ((exponent & 1)==1) {
        result = multiplyToLen(result, result.length, 
                                       baseToPow2, baseToPow2.length, null);
        result = trustedStripLeadingZeroInts(result);
        }
        if ((exponent >>>= 1) != 0) {
                baseToPow2 = squareToLen(baseToPow2, baseToPow2.length, null);
        baseToPow2 = trustedStripLeadingZeroInts(baseToPow2);
        }
    }
    return new BigInteger(result, newSign);
    }

該算法使用重復平方( squareToLen )和乘法( multiplyToLen )。 這些操作的運行時間取決於所涉及的數字的大小。 在計算結束時大數的乘法比開始時的大得多。

乘法僅在此條件為真時執行: ((exponent & 1)==1) 平方運算的數量取決於數字中的位數(不包括前導零),但只有設置為1的位才需要乘法。通過查看二進制文件,可以更容易地看到所需的操作代表人數:

2000000: 0000111101000010010000000
2500000: 0001001100010010110100000
3000000: 0001011011100011011000000
3500000: 0001101010110011111100000
4000000: 0001111010000100100000000
4500000: 0010001001010101000100000
5000000: 0010011000100101101000000

請注意,2.5M和4.5M是幸運的,因為它們設置的高位比周圍的數字少。 下次發生這種情況的時間是8.5M:

8000000: 0011110100001001000000000
8500000: 0100000011011001100100000
9000000: 0100010010101010001000000

甜蜜點是2的精確力量。

1048575: 0001111111111111111111111 // 16408 ms
1048576: 0010000000000000000000000 //  6209 ms

只是一個猜測:

指數是逐位處理的,如果最低有效位是1,則完成另外的工作。

如果L是指數中的位數,A是位數1和t1處理公共部分的時間,t2是LSbit為1時的附加時間處理

那么運行時間就是

L t1 + A t2

或者時間取決於二進制表示中的1的數量。

現在寫一個小程序來驗證我的理論......

我不確定你有多少次運行你的計時。 正如一些評論者指出的那樣,你需要多次操作時間才能獲得好的結果(而且它們仍然可能是錯誤的)。

假設你有好的時間,請記住在數學中可以使用很多快捷方式。 您不必進行操作5 * 5 * 5 * 5 * 5 * 5來計算5 ^ 6。

這是一種更快速地完成它的方法。 http://en.wikipedia.org/wiki/Exponentiation_by_squaring

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM