2010-12-13 9 views
9

Diciamo che ho il seguente frammento di codice:la funzione pow di C si rifiuta di lavorare con esponente variabile

int i; double value; 
for(i = 0; i < CONSTANT; i++) { 
    value = (double)pow(2, i); 
} 

Cercando di compilare il codice produce un "undefined reference to` pow '" errore.

Incluso o escluso math.h non fa alcuna differenza, poiché finisce comunque per essere incluso.

L'innalzamento di 2.0 a un hardcoded funziona correttamente, ma tutto fallisce se sostituisco l'esponente con un'espressione che contiene i.

Cosa sto sbagliando? Grazie.

+0

Che compilatore stai utilizzando? C'è qualche altra possibile dichiarazione di 'pow()'? Potresti citare esattamente l'errore? –

+0

Sto usando GCC e non c'è altra dichiarazione di 'pow'. La domanda è sicuramente risposta; quasi tutte le risposte mi hanno aiutato. Vorrei poter accettare più di uno. :) Grazie a tutti. –

+5

Mentre altri hanno commentato il motivo per cui 'pow' non funzionava, l'intero fatto che stai usando' pow' è un grosso problema con il tuo codice. ** C ha un operatore per la base di esponenti 2 ** e si chiama '<<'. Rimuovi questo uso inutile di 'pow' e sostituiscilo con' 1 << i', e dimentica di 'double'. –

risposta

16

E 'un comportamento molto interessante, e un buon esempio di apprendimento.

per risolvere il problema, aggiungere

-lm 

alla riga di comando gcc (a condizione che si sta utilizzando gcc). Questo dice al compilatore di collegarsi alla libreria matematica.

Quello che sembra essere in corso, è che se si sta utilizzando

pow(2.0, 3); 

il compilatore realizza questa espressione restituisce una costante, e lo fa semplice sostituzione.

Pertanto, non è necessario chiamare alcuna funzione di libreria.

+0

Questa è la spiegazione che stavo per pubblicare. Il compilatore può anche essere in grado di ottimizzare 'pow (n, 2)' a 'n * n', o simili. – zwol

+1

In realtà, come commento di follow-up .. la compilazione di quel loop da solo, con ottimizzazione massima (-O3), in realtà funziona senza -lm. Questo perché il valore non viene ulteriormente utilizzato e il compilatore semplicemente srotola e ottimizza il ciclo inutile e inutile pow(), quindi non ha mai bisogno di chiamare la funzione pow() dalla libreria libm. – qdot

3

È necessario collegare con -lm per includere effettivamente la libreria matematica.

Ha funzionato per un valore hardcoded perché il compilatore ottimizzava la chiamata di pow.

0

http://www.cplusplus.com/reference/clibrary/cmath/pow/

In C, solo la versione prendendo due parametri doppie esiste con questo nome. Gli altri overload sono disponibili solo in C++.

Sembra che non si può passare un int, quindi basta fare i un doppio e che dovrebbe funzionare.

+0

Le "solite conversioni aritmetiche" convertono un int in un double se necessario. Stai abbaiando sull'albero sbagliato. – zwol

+0

E quello merita un segno in basso? Jeez. – acron

+0

È una risposta sbagliata e risponde alla domanda sbagliata. Quindi sì. – zwol

1

Il codice per pow fa parte della libreria matematica. È necessario collegare in tale libreria (oltre alla libreria C che è collegata per impostazione predefinita).

Per farlo, con gcc, specificare -lm dal compilatore invocazione

gcc ... -lm 
+3

Attenzione minima: le opzioni '-l' devono sempre essere posizionate * dopo * tutti i file oggetto sulla riga di comando. Capita di lavorare su alcune distribuzioni Linux, se non lo fai, ma non ci si può fare affidamento. – zwol

3

è necessario collegare contro la libreria matematica:

gcc program.c -lm 

La ragione è che GCC (e alcuni altri compilatori) hanno un built-in pow() funzione per le costanti letterali. Quindi, se chiamate il numero pow() con 2.0 manualmente, il compilatore capirà qual è la risposta e la sostituirà. Con un input variabile, il compilatore deve fare affidamento sulla libreria matematica, alla quale è necessario collegarsi.

Problemi correlati