2011-11-09 10 views
43

C'è un altro modo in Java per calcolare una potenza di un intero? Ora utilizzo Math.pow (a, b), ma restituisce un double, che di solito è molto impegnativo, e sembra meno pulito quando si vogliono usare solo interi (un power risulterà quindi anche in un intero).in Java

C'è qualcosa di semplice come un ** b come in Python?

+2

Questo è un possibile duplicato di questa domanda http://stackoverflow.com/questions/101439/the-most-efficient-way-to-implement-an-integer-based-power-function-powint- int – bpgergo

risposta

21

I numeri interi sono solo 32 bit. Ciò significa che il suo valore massimo è 2^31 -1. Come vedi, per numeri molto piccoli, hai un risultato che non può più essere rappresentato da un numero intero. Ecco perché Math.pow usa il doppio.

Se si desidera la precisione di un numero arbitrario, utilizzare BigInteger.pow. Ma è ovviamente meno efficiente.

+18

+1, è vero. Ma lo considererei bello se gli architetti 'Java' hanno aggiunto' pow (int, int) '. A volte sai che vuoi solo "5^6" e non ti preoccupare del doppio. –

+2

Sto solo supponendo, ma penso che non l'abbiano fatto perché un tale metodo porterebbe a risultati completamente errati nella maggior parte dei casi. Principio di minimo stupore. –

+1

Sì, questo è un buon punto. Ma quando sei un ignorante e lavori con 'int', nulla ti impedisce di convertire in' (int) 'un valore overflow. –

21

No, non c'è qualcosa di più breve a**b

Ecco un semplice ciclo, se si vuole evitare doppie:

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

Se si desidera utilizzare pow e convertire il risultato in a numero intero, immettere il risultato nel modo seguente:

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

'O (n)'? Cattive notizie ... –

+3

@DmitryGinzburg: dato un 'long' è 64 bit, quindi O (n) ha 64 come limite superiore. È davvero così brutto? –

+0

@Thomas no, ti sbagli; se 'b' è' 2_000_000_000', allora dovrai fare operazioni '2e9' invece di' 31' in [altra soluzione] (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

Miglioramento del ciclo 'for':' per (; b> 0; b -) ' – Doorknob

+6

miglioramento serio: piazza la base e dimezza l'esponente ad ogni passaggio –

27

L'algoritmo migliore è basato sulla definizione di potenza ricorsiva di 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 

} 

Il tempo di esecuzione dell'operazione è O (logb). Riferimento: More information

+0

E il metodo' isEven (b) '? È lo stesso con 'b% 2 == 0'? – HendraWD

6

Google Guava dispone di utilità matematiche per numeri interi. IntMath

0

Sono riuscito a modificare (limiti, anche controllare, controllo negativo num) Qx__ risposta. Utilizzare a proprio rischio. 0^-1, 0^-2 ecc .. restituisce 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

librerie matematiche di Guava offrono due metodi che sono utili per il calcolo esatto potenze intere:

pow(int b, int k) calcola b per il k-esimo del potere, e impacchi in caso di overflow

checkedPow(int b, int k) è identico, tranne che getta ArithmeticException in caso di overflow

Personalmente checkedPow() soddisfa la maggior parte dei miei bisogni per intero elevamento a potenza ed è più pulita e saft er che usare le doppie versioni e arrotondamenti, ecc. In quasi tutti i posti in cui desidero una funzione di alimentazione, l'overflow è un errore (o impossibile, ma voglio sapere se l'impossibile diventa possibile).

Se si desidera ottenere un risultato long, è sufficiente utilizzare i metodi LongMath corrispondenti e passare gli argomenti int.

2

Bene si può semplicemente usare Math.pow(a,b) come si è usato in precedenza e basta convertire il suo valore usando (int) prima di esso. Sotto potrebbe essere usato come esempio per questo.

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

dove a e b potrebbe essere double o int valori come si desidera. Ciò convertirà semplicemente il suo output in un valore intero come richiesto.

+0

Non sono d'accordo, se '3.0^1.0 = 2.999999 ...' a causa di errori di arrotondamento, la risposta sarà '2' che è sbagliata. – Hidde

+0

@Hidde Sì, hai ragione, questo sicuramente ha uno svantaggio, grazie per averlo menzionato. Può dare risultati errati ma probabilmente il tuo esempio qui darebbe il risultato corretto come '3.0'. Solo come esempio di errore di arrotondamento per la moltiplicazione' 2.2 * 3.0 = 6.0000005' piuttosto che '6.6'. –

+0

@Hidde Una 'doppia' di Java può rappresentare esattamente tutti gli' '' '' 'Java '. Vedere le specifiche del linguaggio Java, sezione 5.1.2, "[Widening Primitive Conversion] (https://docs.oracle.com/javase/specs/jls/se9/html/jls-5.html#jls-5.1.2) ". –

1

Un semplice (nessun controllo di overflow o per la validità degli argomenti) attuazione della ripetuta squadratura algoritmo per calcolare la potenza:

/** 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; 
} 

La complessità temporale è logaritmica di esponente p (cioè lineare al numero di bit richiesti per rappresentare p).

0

A differenza di Python (dove i poteri possono essere calcolati da un ** b), JAVA non ha un modo così rapido per ottenere il risultato della potenza di due numeri. Java ha funzione denominata pow nella classe Math, che restituisce un valore doppio

double pow(double base, double exponent) 

Ma si può anche calcolare poteri di interi che utilizzano la stessa funzione. Nel seguente programma ho fatto lo stesso e alla fine sto convertendo il risultato in un numero intero (typecasting). Seguire l'esempio:

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 
    } 
} 

In alternativa, Il java.math.BigInteger.pow(int exponent) restituisce un BigInteger il cui valore è (questo^esponente). L'esponente è un numero intero piuttosto che un BigInteger. Esempio:

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

Quando è potenza di 2. Prendere a mente che è possibile utilizzare semplice e veloce 1 < < esponente esempio.

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

Per esponenti più grandi (oltre 31) lungo uso invece

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

btw. in Kotlin avete shl invece di << così

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

Utilizzare la logica di seguito per calcolare la potenza n di una.

Normalmente se si vuole calcolare n potenza di a. Moltiplicheremo 'a' per n numero di volte. La complessità temporale di questo approccio sarà O (n) Dividere la potenza n per 2, calcolare Exponentattion = moltiplicare 'a' fino a n/2 solo. Raddoppia il valore. Ora la complessità temporale è ridotta a 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

Grazie, ma sto cercando un modo che è integrato nella lingua ed è breve. Conosco l'algoritmo per calcolare i poteri. – Hidde