计算整数的幂

Hid*_*dde 57 java math

Java中有没有其他方法可以计算整数的幂?

Math.pow(a, b)现在使用,但它返回一个double,这通常是很多工作,并且当你只想使用ints 时看起来不那么干净(电源也将总是导致int).

有没有a**b像Python 一样简单的东西?

Bay*_*och 37

最佳算法基于a ^ b的递归功率定义.

long pow (long a, int b)
{
    if ( b == 0)        return 1;
    if ( b == 1)        return a;
    if (isEven( b ))    return     pow ( a * a, b/2); //even a=(a^2)^b/2
    else                return a * pow ( a * a, b/2); //odd  a=a*(a^2)^b/2

}
Run Code Online (Sandbox Code Playgroud)

操作的运行时间是O(logb).参考:更多信息

  • 在我的基准测试中,对于整个值范围,这实际上比 [简单循环算法](/sf/answers/564998171/) 慢 2 到 20 倍。这里的递归会带来很多开销。 (6认同)
  • 什么是 `isEven(b)` 方法呢?与`b % 2 == 0` 一样吗? (2认同)
  • 我也想知道...那家伙走了,让我们想知道...马虎的程序员... (2认同)
  • 更好地处理 b<0 的情况以避免无限递归 (2认同)

JB *_*zet 36

整数只有32位.这意味着它的最大值是2^31 -1.如您所见,对于非常小的数字,您很快就会得到一个无法用整数表示的结果.这就是Math.pow使用的原因double.

如果要任意整数精度,请使用BigInteger.pow.但它当然效率低下.

  • +1,这是真的.但如果`Java`架构师添加了`pow(int,int)`,我会认为这很好.你知道有时候你只想要那个"5 ^ 6"并且根本不关心双打. (32认同)
  • 是的,这是一个好点。但是当你是一个无知的人并且使用“int”时,没有什么可以阻止你将溢出的值转换为“(int)”。 (3认同)
  • 我只是在猜测,但我认为他们没有这样做,因为在大多数情况下,这种方法会导致完全错误的结果.最不惊讶的原则. (2认同)
  • 我的意思是,如果将“大多数情况”定义为“针对大多数输入值”,那么Java肯定不应该为int或long输入提供*操作符,因为对于大多数输入而言,乘法将溢出。实际上,即使加法也溢出了大约一半的时间! (2认同)

Pet*_*hev 28

不,没有那么短的东西 a**b

这是一个简单的循环,如果你想避免双打:

long result = 1;
for (int i = 1; i <= b; i++) {
   result *= a;
}
Run Code Online (Sandbox Code Playgroud)

如果要使用pow并将结果转换为整数,请按如下方式转换结果:

int result = (int)Math.pow(a, b);
Run Code Online (Sandbox Code Playgroud)

  • @DmitryGinzburg:如果`long`是64位,则O(n)有64作为上限.这真的很糟糕吗? (5认同)
  • @DmitryGinzburg:在这种情况下你会遇到很多溢出问题.OP的代码不包括参数验证.允许的最大数量应该是64,如果a小到2(并且a = 1则没有意义). (2认同)
  • 在我的基准测试中,对于整个值范围,这实际上比递归 O(log(b)) 算法快 2 倍到 20 倍。递归会带来很大的开销。 (2认同)

Sta*_*ski 13

当它的力量为2时.请记住,你可以使用简单快速的移位表达 1 << exponent

例:

2 2 = 1 << 2= (int) Math.pow(2, 2)
2 10 = 1 << 10=(int) Math.pow(2, 10)

对于较大的指数(超过31),请使用long

2 32 = 1L << 32=(long) Math.pow(2, 32)

顺便说一句.在Kotlin你shl不是<<这样的

(java)1L << 32= 1L shl 32(kotlin)


小智 6

Google Guava具有整数的数学实用程序. IntMath