2011-11-09 58 views
43

Java中有計算整數冪的方法嗎? 現在我使用Math.pow(a,b),但它返回一個double,這通常是很多工作,並且當您只想使用整數時看起來不那麼幹淨(一個權力將始終會導致一個整數)。在Java中計算能力

有沒有像Python一樣簡單的** **?

+2

這是這個問題的一個可能重複http://stackoverflow.com/questions/101439/the-most-efficient-way-to-implement-an-integer-based-power-function-powint- int – bpgergo

回答

21

整數只有32位。這意味着它的最大值是2^31 -1。正如你所看到的,對於非常小的數字,你很快就會有一個無法用整數表示的結果。這就是Math.pow使用double的原因。

如果您想要任意整數精度,請使用BigInteger.pow。但它當然效率較低。

+18

+1,這是真的。但是如果'Java'架構師添加了'pow(int,int)',我會認爲它很好。你知道有時候你只是想要'5^6',根本不在乎雙打。 –

+2

我只是猜測,但我認爲他們並沒有這樣做,因爲這種方法在大多數情況下會導致完全不正確的結果。最不驚訝的原則。 –

+1

是的,這是一個很好的觀點。但是,當你是一個無知的人,而且你用'int'工作時,沒有什麼能阻止你將一個溢出值轉換爲'(int)「。 –

21

沒有,沒有短a**b

這裏的東西是一個簡單的循環,如果你想避免雙打:

long result = 1; 
for (int i = 1; i <= b; i++) { 
    result *= a; 
} 

如果你想使用pow並將結果轉換成以整數,結果如下:

int result = (int)Math.pow(a, b); 
+11

'O(n)'?壞消息...... –

+3

@DmitryGinzburg:給定一個「長」是64位,那麼O(n)有64作爲上限。這真的很糟糕嗎? –

+0

@Thomas不,你錯了;如果'b'是'2_000_000_000',那麼你必須在[其他解決方案]中執行'2e9'操作而不是'31'(http://stackoverflow.com/a/20984477/1828937) –

1
import java.util.*; 
public class Power { 

    public static void main(String args[]) 
    { 
     Scanner sc=new Scanner(System.in); 
     int num = 0; 
     int pow = 0; 
     int power = 0; 

     System.out.print("Enter number: "); 
     num = sc.nextInt(); 

     System.out.print("Enter power: "); 
     pow = sc.nextInt(); 

     System.out.print(power(num,pow)); 
    } 
    public static int power(int a, int b) 
    { 
      int power = 1; 
      for(int c=0;c<b;c++) 
      power*=a; 
      return power; 
     } 

} 
+0

對'for'循環的改進:對於(; b> 0; b - )' – Doorknob

+6

嚴重改進:將基數平方並將每一步的指數減半 –

27

最好的算法是基於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 

} 

運行的運行時間是O(logb)。 參考:More information

+0

'isEven(b)'方法的作用是什麼?與「b%2 == 0」相同嗎? – HendraWD

6

谷歌Guava有整數數學實用程序。 IntMath

0

我設法修改(邊界,甚至檢查,負號檢查)Qx__答案。使用風險自負。 0^-1,0^-2等。返回0

private static int pow(int x, int n) { 
     if (n == 0) 
      return 1; 
     if (n == 1) 
      return x; 
     if (n < 0) { // always 1^xx = 1 && 2^-1 (=0.5 --> ~ 1) 
      if (x == 1 || (x == 2 && n == -1)) 
       return 1; 
      else 
       return 0; 
     } 
     if ((n & 1) == 0) { //is even 
      long num = pow(x * x, n/2); 
      if (num > Integer.MAX_VALUE) //check bounds 
       return Integer.MAX_VALUE; 
      return (int) num; 
     } else { 
      long num = x * pow(x * x, n/2); 
      if (num > Integer.MAX_VALUE) //check bounds 
       return Integer.MAX_VALUE; 
      return (int) num; 
     } 
    } 
2

番石榴的數學庫提供了兩種方法來計算精確的整數冪時有用的:

pow(int b, int k)計算B向第k個功率,和溢出包裝

checkedPow(int b, int k)是相同的,只是它在溢出時拋出ArithmeticException

個人checkedPow()滿足大部分的我的整數的指數的需求和更清潔和SAFT呃比使用雙重版本和四捨五入等等。在幾乎所有我想要功能函數的地方,溢出是一個錯誤(或者不可能,但是我希望被告知是否不可能變成可能)。

如果你想得到一個long結果,你可以使用相應的LongMath方法並通過int參數。

2

那麼你可以簡單地使用Math.pow(a,b)像你之前使用的那樣,只需在它之前使用(int)來轉換它的值。下面可以作爲一個例子。只要你想

int x = (int) Math.pow(a,b); 

其中ab可能是doubleint值。 這將簡單地將其輸出轉換爲一個整數值,如您所需。

+0

我不同意,如果'3.0^1.0 = 2.999999 ...'由於舍入錯誤,答案將是'2',這是錯誤的。 – Hidde

+0

@Hidde是的,你是對的朋友,這當然有一個缺點,謝謝提及。它可能會給出錯誤的結果,但是在這裏你的例子可能會給出正確的結果,例如'3.0'。只是作爲乘法'2.2 * 3.0 = 6.0000005'而不是'6.6'的舍入誤差的一個例子。 –

+0

@Hidde Java'double'可以完全代表所有Java'ints'。請參閱Java語言規範,第5.1.2節「[加寬基元轉換](https://docs.oracle.com/javase/specs/jls/se9/html/jls-5.html#jls-5.1.2) 」。 –

1

一個簡單的(沒有檢查溢出或用於參數有效性)實現其重複平方用於計算所述功率的算法:

/** Compute a**p, assume result fits in a 32-bit signed integer */ 
int pow(int a, int p) 
{ 
    int res = 1; 
    int i1 = 31 - Integer.numberOfLeadingZeros(p); // highest bit index 
    for (int i = i1; i >= 0; --i) { 
     res *= res; 
     if ((p & (1<<i)) > 0) 
      res *= a; 
    } 
    return res; 
} 

的時間複雜度是對數以指數p(即線性的數代表p所需的位)。

0

與Python(其中權力可以通過** b計算)不同,JAVA沒有這樣的快捷方式來完成兩個數字的結果。 Java有在數學類函數命名爲戰俘,它返回一個Double值

double pow(double base, double exponent) 

但你也可以計算出使用相同的功能整數的權力。在下面的程序中,我做了同樣的事情,最後我將結果轉換爲整數(類型轉換)。按照例如:

import java.util.*; 
import java.lang.*; // CONTAINS THE Math library 
public class Main{ 
    public static void main(String[] args){ 
     Scanner sc = new Scanner(System.in); 
     int n= sc.nextInt(); // Accept integer n 
     int m = sc.nextInt(); // Accept integer m 
     int ans = (int) Math.pow(n,m); // Calculates n^m 
     System.out.println(ans); // prints answers 
    } 
} 

或者, 的java.math.BigInteger.pow(int exponent)返回一個BigInteger,其值是(this ^指數)。指數是一個整數而不是BigInteger。例如:

import java.math.*; 
public class BigIntegerDemo { 
public static void main(String[] args) { 
     BigInteger bi1, bi2; // create 2 BigInteger objects   
     int exponent = 2; // create and assign value to exponent 
     // assign value to bi1 
     bi1 = new BigInteger("6"); 
     // perform pow operation on bi1 using exponent 
     bi2 = bi1.pow(exponent); 
     String str = "Result is " + bi1 + "^" +exponent+ " = " +bi2; 
     // print bi2 value 
     System.out.println(str); 
    } 
} 
1

當它2.記住拿,你可以用簡單而快速的1 < <指數 例子的力量。

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

對於較大的指數(超過31)使用長代替

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

順便說一句。在科特林你有shl代替<<所以

1L << 32 == 1L shl 32 
0

使用下面的邏輯來計算的n次方。

通常情況下,如果我們想計算n的冪。我們將乘以'n'n次。這種方法的時間複雜度將爲O(n) 將冪n除以2,計算Exponentattion =乘'a'直到n/2。將價值加倍。現在時間複雜度降低到O(n/2)。

public int calculatePower1(int a, int b) { 
      if (b == 0) { 
       return 1; 
      } 

      int val = (b % 2 == 0) ? (b/2) : (b - 1)/2; 


      int temp = 1; 
      for (int i = 1; i <= val; i++) { 
       temp *= a; 
      } 


      if (b % 2 == 0) { 
       return temp * temp; 
      } else { 
       return a * temp * temp; 
      } 

     } 
+0

謝謝,但我正在尋找一種內置於語言中的方式,並且很短。我知道計算能力的算法。 – Hidde