java.math.BigInteger pow(指数)问题

时间:2010-05-28 22:17:22

标签: java biginteger exponent pow

我对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);
    }

3 个答案:

答案 0 :(得分:9)

该算法使用重复平方(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 :(得分:1)

只是一个猜测:

指数逐位处理,如果最低有效位为1,则完成另外的工作。

如果L是指数中的位数 和A的位数为1 和t1处理公共部分的时间 和t2当LSbit为1时的附加时间处理

然后运行时间

L t1 + A t2

或时间取决于二进制表示中的1的数量。

现在写一个小程序来验证我的理论......

答案 2 :(得分:1)

我不确定你有多少次运行你的计时。正如一些评论者指出的那样,你需要多次操作时间才能获得好的结果(而且它们仍然可能是错误的)。

假设你有好的时间,请记住在数学中可以使用很多快捷方式。您不必进行操作5 * 5 * 5 * 5 * 5 * 5来计算5 ^ 6。

这是一种更快速地完成任务的方法。 http://en.wikipedia.org/wiki/Exponentiation_by_squaring