È 2 ** x più veloce da calcolare di exp (x)?


12

Perdona l'ingenuità che sarà ovvia nel modo in cui faccio questa domanda e nel fatto che la sto facendo.

I matematici in genere usano quanto è la base più semplice / più bella in teoria (a causa del calcolo). Ma i computer sembrano fare tutto in binario, così è più veloce su una macchina per calcolare di quanto ?exp2**xMath::exp(x)


7
Di che tipo di numero stai parlando? Numero intero di dimensioni arbitrarie? Virgola mobile a dimensione fissa? Virgola mobile di precisione arbitraria?
Gilles 'SO- smetti di essere malvagio' il

@Gilles È un buon punto. Non avevo capito che la differenza fosse importante.
isomorfismi

3
Ho visto su alcuni calcolatori tascabili Casio che registrare e la potenza di un numero non-e è molto più lento di ln / exp
phuclv

2
Per rischiare di essere schietto, hai provato a cronometrarli entrambi e vedere quale è più veloce? O stai parlando di velocità in un senso di complessità ? O(f(n))
jmite,

1
La lingua è incaricata di selezionare il modo più veloce e farà un buon lavoro. Solo nel caso in cui sia richiesta la massima velocità, e le misurazioni hanno dimostrato che ciò è rilevante per le prestazioni se dovresti preoccuparti di questo tipo di cose
vonbrand,

Risposte:


18

Dato che si tratta di CS e non StackOverflow, suppongo che tu stia facendo una domanda sull'analisi numerica e (per semplificare le cose) in particolare IEEE-754 in virgola mobile. In tal caso, la risposta alla tua domanda dipende in parte da cosa intendi per "più facile" e in parte dai dettagli del sistema.

Nessuna CPU moderna di cui sono a conoscenza ha un'istruzione integrata che fa esattamente quello che ti aspetteresti sia per l' operazione (che d'ora in poi chiameremo , il suo solito nome in C) o 2 x ( ). Entrambi sono implementati utilizzando le funzioni di libreria.exexp2xexp2

Come nel caso di tutti i metodi numerici per le operazioni trascendentali, ci sono alcuni casi speciali da considerare:

exp(NaN) = NaN
exp(+Inf) = +Inf
exp(-Inf) = 0

Tuttavia, c'è un'altra cosa che rende il problema leggermente meno complicato: il dominio utile è piuttosto piccolo. Per binary32, exp(x)underflow se o giù di lì, e overflow se x > 88.7 o giù di lì. Insolitamente per le operazioni trascendentali, possiamo anche ignorare il caso subnormale, poiché è indistinguibile da se è subnormale. Tutto quanto sopra vale anche per , tranne per il fatto che il dominio è leggermente diverso.x<104x>88.7exp(x)1.0xexp2

ex=2x/ln21ln2exp2K

exp2(x)=2n×T[j]×P(y)

nxT2j/Kj[0,K)P2x[0,1K)2nTP

f2xm12x1x[1,1]

Sebbene x87 supporti le istruzioni trascendenti, l'implementazione della libreria software della funzione trascendentale può essere più veloce in molti casi.

Modifica: è stato sottolineato nei commenti che dovrei spiegare alcune delle nuove terminologie utilizzate in IEEE 754-2008. Parte della lingua è cambiata dal 1985 al 1987 e la maggior parte delle persone ha molta più familiarità con il vecchio gergo.

I termini "binary32" e "binary64" sono i nuovi nomi per i numeri a virgola mobile binari a 32 e 64 bit, che il vecchio standard chiamava rispettivamente "singolo" e "doppio".

Il termine "numero subnormale" sostituisce il precedente "numero denormale" o "numero denormalizzato" .


quando dici "subnormale" - chiaramente non intendi "sub-gaussiano"; vuoi dire "peggio di [qualche punto di riferimento della tipicità]"?
isomorfismi

2
@isomorphismes In questo caso, "subnormale" è relativo alla modalità di implementazione dei float. Vedi i numeri denormali su Wikipedia.
Paul Manta,

Per inciso, ho semplificato troppo il "metodo tipico" solo un po '. È possibile implementare exp2 () ed exp () con precisione ulp usando solo una piccola (e abbastanza facile da capire) estensione del metodo qui presentato, ma una spiegazione della piccola estensione di facile comprensione probabilmente raddoppierebbe la lunghezza di la risposta!
Pseudonimo

6

2**x2x<<1 << x


4
Non attualmente. x forse un tipo a virgola mobile
phuclv

1
x

Se xnon è un numero intero (diciamo, 20.75), dovresti impostare la mantissa 2e l'esponente sul valore arrotondato di xcome stima più accurata (la rappresentazione precisa non è possibile). Anche questo è molto più veloce di `pow´.
Damon,

1

Se 2**xè una funzione sugli interi, sono d'accordo con la risposta di Stephen, il cambio è più economico. Ma di solito vedo che come 2^xe **per indicare l'espiazione in virgola mobile. Per questo caso, mi aspetterei prestazioni simili tra **e ^poiché entrambi expe pow(l'operazione sottostante per **) sono entrambe operazioni di approssimazione trascendentale.


Interessante, non sapevo **fosse considerato un sinonimo della versione in virgola mobile (e, sciocco me, avevo dimenticato che i due sarebbero stati diversi).
isomorfismi

1

Poiché 2 ^ x = e ^ (x * ln 2) ed e ^ x = 2 ^ (x * log2 (e)), non ti aspetteresti molta differenza.

Per x vicino a zero, di solito si usa un polinomio e ^ x = 1 + x + x ^ 2/2 + x ^ 3/6 ..., ottimizzato per tagliare il prima possibile mantenendo piccolo l'errore di arrotondamento . Chiaramente 2 ^ x è molto più lento da calcolare. "x vicino a 0" di solito sono valori di x dove sqrt (1/2) <= e ^ x <= sqrt (2). Limitando l'intervallo di x si assicura che il grado polinomiale non debba essere scelto troppo alto.

Per x più grandi, di solito si calcola 2 ^ x lasciando x = x '+ x' ', dove x' è un numero intero e -0.5 <= x '' <= 0,5. 2 ^ x 'verrebbero quindi calcolati costruendo un numero in virgola mobile con il modello di bit destro e 2 ^ x' 'usando il metodo e ^ x per la piccola x. Qui, 2 ^ x è un po 'più veloce. Inoltre, se x è di grandi dimensioni (diciamo x = 100.3), la semplice moltiplicazione di x per log2 (e) introdurrebbe un errore di arrotondamento inaccettabile (perché ci sono molti meno bit frazionari), quindi è necessario prestare maggiore attenzione.

E si spera che una buona funzione di libreria si preoccupi che ogni volta che x <= y, e ^ x <= e ^ y e 2 ^ x <= 2 ^ y, indipendentemente dagli errori di arrotondamento. Raggiungere quel tipo di cose può essere complicato.


0

Devi capire che la matematica su un computer è fatta in modi diversi da software diversi, si spera che fornisca risposte coerenti. Guardando la maggior parte dei software, penso che i computer si comportino come i computer e calcoleranno la risposta a lungo, anche per 0 ^ 0. Il problema è che casi speciali implicano il "riconoscimento" che non si verifica gratuitamente nei computer digitali. Ciò significa che solo in quei casi in cui avere la risposta accelererà le cose "il più" si verificherà l'ottimizzazione. Ma in questi casi accadrà estremamente bene. Inoltre, per ottenere la risposta giusta potrebbe essere necessario eseguire diversi riconoscimenti. Questo si chiama livelli di ottimizzazione della velocità e ciò si è verificato nella massima misura professionale sulla base della maggior parte dei software chiamati GNU "C". Questo perché qui vengono utilizzate differenze minime nel tempo di esecuzione da software a software e da macchina a macchina come dati di accettazione della qualità. In altri interpreti di solito solo se si verifica una "bandiera zero" come effetto collaterale di calcoli precedenti si accelera il riconoscimento. come 0 * x => C0.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.