@Blindy parla di possibili approcci che Java potrebbe adottare nell'implementazione di pow
.
Prima di tutto, il caso generale non può essere ripetuto moltiplicando. Non funzionerà nel caso generale in cui l'esponente non è un numero intero. (! La firma per pow
è Math.pow(double, double)
)
Nel OpenJDK 8 codebase, l'implementazione del codice nativo per pow
può funzionare in due modi:
La prima implementazione in e_pow.c
utilizza una serie di potenze. L'approccio è descritto nei commenti C come segue:
* Method: Let x = 2 * (1+f)
* 1. Compute and return log2(x) in two pieces:
* log2(x) = w1 + w2,
* where w1 has 53-24 = 29 bit trailing zeros.
* 2. Perform y*log2(x) = n+y' by simulating multi-precision
* arithmetic, where |y'|<=0.5.
* 3. Return x**y = 2**n*exp(y'*log2)
la seconda implementazione in w_pow.c
è un involucro per la funzione pow
fornito dalla libreria standard C. Il wrapper si occupa di casi limite.
Ora è possibile che la libreria C standard utilizzi le istruzioni matematiche specifiche della CPU. In caso affermativo, e la build JDK (o runtime) ha selezionato la seconda implementazione, quindi Java avrebbe utilizzato anche queste istruzioni.
Ma in entrambi i casi, non vedo traccia di alcun codice di caso speciale che utilizza ripetute moltiplicazioni. Puoi tranquillamente supporre che sia O(1)
.
1 - non ho approfondito il modo in cui la selezione è/può essere fatto.
fonte
2015-09-06 01:20:08
se si desidera solo potenze di interi, scrivere la propria funzione di potenza è meglio. Dato che ci sono solo poche potenze di 10 che si adattano a un int, usa semplicemente una tabella di ricerca e stai bene con O (1) –
@ LưuVĩnhPhúc, ma facendo iterativamente significa che fai b operazioni per a^b. non è vero? Nella domanda originale, se la lunghezza dell'array è n, l'intervallo dell'array è compreso tra 0 e n e il valore massimo è almeno n-1. Quindi il codice sopra avrà la complessità O (n^2) no? –
Dove ho detto che fai in modo iterativo i poteri? Quello che ho detto è una [tabella di ricerca] (https://en.wikipedia.org/wiki/Lookup_table) come 'int pow10 [] = {1, 10, 100, 1000, ... 1000000000};' e per ottenere 'Math.pow (10, i)' usa semplicemente 'pow10 [i]'. Anche se moltiplichi manualmente, hai solo bisogno di O (log n) con [esponenziazione per quadratura] (https: //en.wikipedia.org/wiki/Exponentiation_by_squaring) ([Il modo più efficace per implementare una funzione di potenza basata su interi pow (int, int)] (http://stackoverflow.com/q/101439/995714), non come O (n) come fare it itativamente –