2012-12-12 19 views
18

Ho bisogno di valutare un logaritmo di qualsiasi base, non importa, con una certa precisione. C'è un algoritmo per questo? Programmo in Java, quindi sto bene con il codice Java.Algoritmo logaritmo

How to find a binary logarithm very fast? (O(1) at best) potrebbe essere in grado di rispondere alla mia domanda, ma non lo capisco. Può essere chiarito?

+0

I trucchi menzionati in questa domanda sfruttano il modo in cui i numeri vengono memorizzati nella memoria. Faresti meglio a fare affidamento sui metodi di Math (o BigInteger/BigDecimal) se non comprendi pienamente questi trucchi. Ad ogni modo, sfruttano il fatto che i numeri sono internamente rappresentati molto vicino alla loro rappresentazione nella base 2. In Java non ci sono sindacati, invece si ottengono i bit grezzi di un doppio tramite [Double.doubleToRawLongBits] (http: // docs .oracle.com/JavaSE/6/docs/api/java/lang/Double.html # doubleToRawLongBits (doppio)). – ignis

+0

BigInteger e BigDecimal non contengono metodi di registro. – Justin

+0

esattamente. per ints usa quel ovvio spostamento di bit in un ciclo contato. – vaxquis

risposta

58

Usa questa identità:

registro b (n) = log e (n)/log e (b)

Dove log può essere una funzione logaritmica in qualsiasi base, n è il numero e b è la base. Ad esempio, in Java questo troverà il logaritmo in base 2 di 256:

Math.log(256)/Math.log(2) 
=> 8.0 

Math.log() usi di base e, tra l'altro. E c'è anche Math.log10(), che utilizza la base 10.

+0

Conosco quell'identità. Voglio calcolare un logaritmo con più precisione di quanto possa dare un doppio. – Justin

+1

@ user1896169 in tal caso, passare a 'BigDecimal' e utilizzare questa [ricetta] (http://stackoverflow.com/questions/739532/logarithm-of-a-bigdecimal) per calcolare il logaritmo –

+0

Math.log() predefinito base è e – Suranga