2016-01-17 4 views
5

ho usato per sostituire const con #define, ma nel seguente esempio la stampa falsa.const vs # define (comportamento strano)

#include <iostream> 
#define x 3e+38 

using namespace std; 

int main() { 
    float p = x; 
    if (p==x) 
     cout<<"true"<<endl; 
    else 
     cout<<"false"<<endl; 
return 0; 
} 

Ma se sostituisco

#define x 3e+38 

con

const float x = 3e+38; 

funziona perfettamente, domanda è: perché? (So ​​che ci sono diversi argomenti discussi per #define vs const, ma in realtà non ho capito, gentilmente mi illumini)

+4

Prova '#define x 3e + 38f' –

+0

Waow, ma perché non funziona, così come perché e come funziona? –

+0

Non usare '==' per confrontare float/double – adrianm

risposta

5

In C++ i letterali sono a doppia precisione. Nei primi esempi, il numero 3e + 38 viene prima convertito in float nell'inizializzazione della variabile e quindi in doppia precisione nel confronto. Le conversioni non sono necessarie, quindi i numeri potrebbero essere diversi. Nel secondo esempio, i numeri restano sempre fluttuanti. Per risolvere il problema è possibile modificare p a double, prego scrivere

#define x 3e+38f 

(che definisce un galleggiante letterale), o modificare il confronto

if (p == static_cast<float>(x)) 

che esegue la stessa conversione inizializzazione delle variabili, e fa quindi il confronto in un'unica precisione.

altresì commentato il confronto di numeri in virgola mobile con == solito non è una buona idea, come errori di arrotondamento ottengano risultati inattesi, ad esempio, x*y potrebbe essere diverso da y*x.

+1

qual è il modo giusto per confrontare i punti mobili? –

+0

In confronto a 'A' e' B' puoi fare qualcosa come 'if (fabs (A-B)

+0

in condizioni normali, qual è la precisione per '(a_float == b_float)'? –

1

Il numero 3e + 38 è doppio a causa della sua grandezza.

L'assegnazione

float p = x; 

provoca l'3e + 38 perda la sua precisione e quindi il suo valore se conservate in p.

ecco perché il confronto:

if(p==x) 

risultati in falso perché p ha un valore diverso da 3e + 38.

+0

Non è la grandezza che rende '3e + 38 –