2010-10-03 7 views
0

Je ne comprends pas pourquoi mon programme faire ces calculs:calcul étrange

#define PixelsPerMeter 40.0 

// 40 pixels ~ 1 meter 
#define Meters2Pixels(meters) (float)meters*PixelsPerMeter 
#define Pixels2Meters(pixels) (float)pixels/PixelsPerMeter 

// The speed of free falling 
#define G Meters2Pixels(9.81) 

// ... 
float mHeight = 768; 
float _windPower = Meters2Pixels(-5.0); 
// ... 

float x1 = (mHeight/G) * _windPower; 

cout << "G: " << G << "; wind: " << _windPower << "\n"; 
cout << "Height: " << mHeight << "\n"; 
cout << "Calculating: " << mHeight/G * _windPower << "\n"; 

=> 
G: 392.4; wind: -200 
Height: 768 
Calculating: -626300 

Je ne comprends pas pourquoi ... Si je Calculation par les mains, par exemple, je dois obtenir: -391.4

Qu'est-ce qui ne va pas?

Répondre

4

Vous devez joindre les extensions macro entre parenthèses comme:

#define Meters2Pixels(meters) ((float)meters*PixelsPerMeter) 
#define Pixels2Meters(pixels) ((float)pixels/PixelsPerMeter) 

Le C/C++ préprocesseur une substitution aveugle. Sans la parenthèse, x1 sera calculée comme suit:

float x1 = (mHeight/(float)9.81*40.0) * _windPower; 

qui divise mHeight par 9.81 et multiplie ensuite le résultat avec 40.0. Ce que tu ne veux pas. Vous voulez mHeight être divisé par le produit de 9.81 et 40.0 d'où la parenthèse.

vous pouvez toujours voir comment vos macros s'élargir avant votre fichier va pour la compilation en utilisant l'option -E de g++ comme:

g++ -Wall -E myfile.cpp 

EDIT:

Il est également préférable de joindre la macro paramètre entre parenthèses ainsi, cela vous gardera si vous passez une expression (comme dire Meters2Pixels(foo + 2):

+1

Je vous recommande également d'inclure également les arguments de macro entre parenthèses, dans le cas où vous transmettez une valeur qui change la priorité de votre opérateur pour quelque chose d'indésirable. – mdec

+0

Bonne réponse, merci. Oui, les macros sont mauvaises :) – Ockonal

+0

Les macros ne sont pas mauvaises, mais je ne pense pas que ce soit un bon cas d'utilisation. – alternative

3

Pour éviter les problèmes avec les macros, vous devriez envisager d'utiliser des fonctions intégrées.