Problème de multiplication de doubles

Problème de multiplication de doubles - C++ - Programmation

Marsh Posté le 13-06-2008 à 10:02:20    

Bonjour tout lemonde  
 
J'ai un probème que je n'arrive pas à résoudre depuis quelques jours et ce n'est pas faute d'avoir chérché...
Voici mon code

Code :
  1. double x=exp(-((_Touverture+Tarc)-_Tfermeture)/_T);
  2. double y=_ModuleI*sin(0+(_alpha-_phi)*pi/180);
  3. double z=_ModuleI*sin(2*pi*_f*(_Touverture+Tarc)/1000+0+(_alpha-_phi)*pi/180);
  4. double ph1tc = z-y*x;

 
J'ai ph1tc=-9.2559631349317831e+061 alors que z=0.81462211321630484, x=0.25394129165067114 et y=-0.99026806534391931
 
Le problème doit venir de la reconversion en décimale aprés la multiplication.
Est ce que quelqu'un peut m'aider??
J'avais penser à limiter le nombre de chiffres après la virgule dans tout les calculs (opérations arithmétiques mais aussi dans les calculs de sinus et d'exponentiels) mais ca je ne sais pas faire et je dois avoir une bonne précision donc pas mal de chiffres...
Merci baucoup pour votre aide..
 

Reply

Marsh Posté le 13-06-2008 à 10:02:20   

Reply

Marsh Posté le 13-06-2008 à 11:09:25    

euh 0.8 - (-0.99 * 0.25) ça fait bien du 1.06.
 

Code :
  1. cat mult.cpp
  2. #include <iostream>
  3. int main()
  4. {
  5.         double z=0.81462211321630484, x=0.25394129165067114, y=-0.99026806534391931;
  6.         double ph1tc = z - y * x;
  7.         std::cout << ph1tc << '\n';
  8. }
  9. [l0247308@x-pau-101624 tmp]$ g++ -Wall mult.cpp && ./a.out
  10. 1.06609

Reply

Marsh Posté le 13-06-2008 à 11:19:36    

Je suis sous visual c++ et ca ne marche pas pareil...

Reply

Marsh Posté le 13-06-2008 à 11:30:17    

Je ne vois pas bien ce que le compilateur vient faire là-dedans.
 
Y a pas un "e+??" après z, x ou y ?

Reply

Marsh Posté le 13-06-2008 à 11:53:24    

t'as compilé le même bout de code que moi et tu n'as pas de résultat similaire ?

Reply

Marsh Posté le 13-06-2008 à 13:30:37    

inblack a écrit :

Je suis sous visual c++ et ca ne marche pas pareil...

 

moi aussi et ça marche pareil (encore heureux d'ailleurs)


Message édité par kyntriad le 13-06-2008 à 13:30:53

---------------
You can't start a fire with moonlight
Reply

Marsh Posté le 13-06-2008 à 14:28:11    

Taz quand j'essaie ton code ca marche mais en réalité les valeurs reelle de x y et z(celles calculés par le compilateur) doivent contenir bcp plus de chiffres apres la virgule (plus que les 64 bits autorisés par un double donc ils sont tranqués et stockés dans x,y et z) et donc puisque les valeurs de x y et z correspondent déja au maximum que peut contenir un double, le fait de les multiplier donne des valeurs qui devrait etre stockés sur 128 bits par exemple...ce qui conduit a des valeurs aberrantes si on les stocke sur 64 bits....
C'est mon intérprétation.... est ce que je me trompe...
c'est pour ca que j'ai pensé a limiter le nombre des chiffres apres la virgule dans tous les calculs que je fait...
en fait j'ai décomposé ca en x y z pour voir d'ou vient le probleme mais j'ai pleins de calculs comme ca a faire et il me faut une méthode qui marche a tout les coups...

Reply

Marsh Posté le 13-06-2008 à 14:35:05    

Tu te trompes. T'as beau multiplier 0.33 ou 0.330000000000000012468416574687416354124254, ça ne donnera jamais 9e+61.


Message édité par Elmoricq le 13-06-2008 à 14:35:33
Reply

Marsh Posté le 13-06-2008 à 14:35:22    

Est-ce que toutes tes variables intermédiaires sont bien des doubles aussi ?
 
Envoie un peu plus de code sinon qu'on puisse voir le problème. Ca m'étonnerai fort que tes souçis soient dus à un dépassement des capacité.


---------------
You can't start a fire with moonlight
Reply

Marsh Posté le 13-06-2008 à 14:45:35    

Code :
  1. int A=0;
  2. int & a=A;
  3. double & I1ret=I1exact;
  4. double Equations_CO::I1(double t)
  5. {
  6. double ph1=_ModuleI*sin(2*pi*_f*t/1000+0+(_alpha-_phi)*pi/180)-_ModuleI*sin(0+(_alpha-_phi)*pi/180)*exp(-(t-_Tfermeture)/_T);
  7. double x = exp(-((_Touverture+Tarc)-_Tfermeture)/_T);
  8. double y = _ModuleI*sin(0+(_alpha-_phi)*pi/180);
  9. double z = _ModuleI*sin(2*pi*_f*(_Touverture+Tarc)/1000+0+(_alpha-_phi)*pi/180);
  10. double  ph1tc = z-y*x;
  11. double d = 1.732/2*_ModuleI*sin(2*pi*_f*t/1000-pi/6+(_alpha-_phi)*pi/180);
  12. double e = (_Touverture+Tarc)/_T;
  13. double f = (ph1tc-1.732/2*_ModuleI*sin(2*pi*_f*(_Touverture+Tarc)/1000-pi/6+(_alpha-_phi)*pi/180)*exp(-(t-_Tfermeture)/_T));
  14. double ph1bi = d-e*f;

Reply

Marsh Posté le 13-06-2008 à 14:45:35   

Reply

Marsh Posté le 13-06-2008 à 14:47:41    

au niveau du debogage je m'arrete la donc c pas la peine de vous donner la suite...sinon pour les valeurs des variable utilisées:

Code :
  1. Equations_CO::Equations_CO()
  2. {
  3. this->_f=50;
  4. this->_ModuleI=1;
  5. this->_T=23; 
  6. this->_phi=82.12l;
  7. this->_alpha=0;
  8. this->_t=0l;   
  9. this->_Tarcmin=5.82l;
  10. this->_Tfermeture=20.00l;
  11. this->_Touverture=100.00l;
  12. this->_Tessai=120.00l;
  13. this->_Tarcmin=5.82l;
  14. this->_Parc=40l;
  15. this->_Marc=5*_Parc;
  16. this->_Pas=0.015l;
  17. this->_offset=0l;
  18. this->_bruit=0l;
  19. }


Reply

Marsh Posté le 13-06-2008 à 15:10:53    

j'ai mis des "l" à la suite des valeurs parce que j'avais lu un truc dans un bouquin que j'ai pas tres bien compris d'ailleurs mais en fait ca ne change rien à mon problème...

Reply

Marsh Posté le 13-06-2008 à 15:23:04    

inblack a écrit :

Code :
  1. int A=0;
  2. int & a=A;
  3. double & I1ret=I1exact;
  4. double Equations_CO::I1(double t)
  5. {
  6. double ph1=_ModuleI*sin(2*pi*_f*t/1000+0+(_alpha-_phi)*pi/180)-_ModuleI*sin(0+(_alpha-_phi)*pi/180)*exp(-(t-_Tfermeture)/_T);
  7. double x = exp(-((_Touverture+Tarc)-_Tfermeture)/_T);
  8. double y = _ModuleI*sin(0+(_alpha-_phi)*pi/180);
  9. double z = _ModuleI*sin(2*pi*_f*(_Touverture+Tarc)/1000+0+(_alpha-_phi)*pi/180);
  10. double  ph1tc = z-y*x;
  11. double d = 1.732/2*_ModuleI*sin(2*pi*_f*t/1000-pi/6+(_alpha-_phi)*pi/180);
  12. double e = (_Touverture+Tarc)/_T;
  13. double f = (ph1tc-1.732/2*_ModuleI*sin(2*pi*_f*(_Touverture+Tarc)/1000-pi/6+(_alpha-_phi)*pi/180)*exp(-(t-_Tfermeture)/_T));
  14. double ph1bi = d-e*f;



 
ça te dit pas de sortir quelques constantes ?


Message édité par bjone le 13-06-2008 à 15:23:15
Reply

Marsh Posté le 13-06-2008 à 15:26:32    

deja fait..regarde plus haut

Reply

Marsh Posté le 13-06-2008 à 15:31:34    

Il manque les déclarations de _ModuleI, _phi, _alpha, _T, _t...


---------------
You can't start a fire with moonlight
Reply

Marsh Posté le 13-06-2008 à 15:34:25    

inblack a écrit :

au niveau du debogage je m'arrete la donc c pas la peine de vous donner la suite...sinon pour les valeurs des variable utilisées:

Code :
  1. Equations_CO::Equations_CO()
  2. {
  3. this->_f=50;
  4. this->_ModuleI=1;
  5. this->_T=23; 
  6. this->_phi=82.12;
  7. this->_alpha=0;
  8. this->_t=0;   
  9. this->_Tarcmin=5.82;
  10. this->_Tfermeture=20.00;
  11. this->_Touverture=100.00;
  12. this->_Tessai=120.00;
  13. this->_Tarcmin=5.82;
  14. this->_Parc=40;
  15. this->_Marc=5*_Parc;
  16. this->_Pas=0.015;
  17. this->_offset=0;
  18. this->_bruit=0;
  19. }




c'est ce que tu veux?
je l'avais posté plus haut mais en
 fait je retire les "l" parce que ca ne sert a rien

Reply

Marsh Posté le 13-06-2008 à 15:35:45    

Sinon t'as ca aussi:

Code :
  1. class Equations_CO
  2. {
  3. /*
  4. f: Frequence du signal a générer
  5. ModuleI: Module du courant(Courant maximun).
  6. ModuleV: Module de tension (Tension maximum).
  7. T: Constante de temps.
  8. phi: Déphasage entre le courant et la tension.
  9. alpha: Etablissement de I1 par rapport au zero en V1 (en °).
  10. bruit: Bruit blanc à ajouter au signal.
  11. Offset:  
  12. Tarcmin: Temps d'arc (caractéristique des appareils a tester).
  13. Tfermeture: Instant de fermeture des contatcts.
  14. Touverture: Instant de séparation des contacts.
  15. Parc: Pied d'arc caractéristique des appareils a tester (permet de determiner la tension d'arc).
  16. Marc: Maximum de l'arc (permetant aussi la détermination de la tension d'arc.
  17. t: temps
  18. */
  19. private:
  20. int _f,_ModuleI,_ModuleV,_T;
  21. double _phi,_alpha,_bruit,_offset,_Tarcmin,_Tfermeture,_Touverture,_Parc,_Marc,_t;
  22. public:
  23. double _Tessai,_Pas;
  24. Equations_CO();//Constructeur par defaut
  25. Equations_CO(int,int,int,int,double,double,double,double,
  26.     double,double,double,double,double,double,double,double);
  27. ~Equations_CO(void);
  28. double I1(double);
  29. double I2(double);
  30. double I3(double);
  31. double V1(double);
  32. double V2(double);
  33. double V3(double);
  34. };

Reply

Marsh Posté le 13-06-2008 à 16:01:30    

inblack a écrit :

deja fait..regarde plus haut


non:

Code :
  1. double x = exp(-((_Touverture+Tarc)-_Tfermeture)/_T);
  2. double y = _ModuleI*sin(0+(_alpha-_phi)*pi/180);
  3. double z = _ModuleI*sin(2*pi*_f*(_Touverture+Tarc)/1000+0+(_alpha-_phi)*pi/180);


 
ça peut faire:

Code :
  1. const double Toa = _Touverture+Tarc;
  2. const double alphi = ( _alpha - _phi )*M_PI/180.;
  3. double x = exp(  ( Tfermeture -Toa ) / _T );
  4. double y = _ModuleI * sin( alphi );
  5. double z = _ModuleI * sin( 2*M_PI * _f  * Toa / 1000. + alphi );


 
enfin simplifier, réduire, réutiliser des calculs, aérer, tout ça....
et les variables avec _ ça pue.
pi est déjà défini dans maths.h (cmaths) comme M_PI, y'a un define a mettre stout.


Message édité par bjone le 13-06-2008 à 16:04:26
Reply

Marsh Posté le 13-06-2008 à 16:34:38    

utilise un truc de vérif mémoire. tu dois bousiller ta pile à tous les coups. Ou bien fourni nous un code minimal et compilable.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed