Bonjour,

Je travail actuellement sur un projet d'informatique qui consiste à manipuler et travaillé sur des polynômes complexe. Sur le projet en lui même je m'en sort bien. Cependant je rencontre un problème qui me bloque par une boucle infini dans ma fonction pour effectuer la division euclidienne de deux polynôme complexe (je l'ai rencontré seulement sur cette fonction pour l'instant). Le problème ne vient pas de l'implémentation de ma fonction qui est juste mais de la manière dont la machine traite les nombre a virgule, effectue des calcules et les simplifies (plus précisément lors de la multiplication ou la division de deux nombre flottant).
Je ne vais pas mettre ma fonction de division du fait de sa taille et et du nombre de fonction tierce quel appelle qui sont elle même assez imposante (addition de polynôme, soustraction de polynôme , multiplication de polynôme). J'ai donc réaliser un exemple de mon problème avec un petit code effectuant une partie du calcule de la division euclidienne de deux polynôme.
l'exemple est extrait du calcule de la division euclidienne suivante: (2+5i)z^3+(4+i)z^2+(3+2i)z+1+i divisé par (4+5i)z^2+(2+3i)z+6+2i)
après avoir fait la première soustraction et donc éliminé de z^3. La boucle se fait car le z^2 ne s'élimine jamais.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <complex.h>
int main(){
	float complex R=4+1*I;
	printf("R: %g + %gi (%f + %fi) \n",creal(R),cimag(R),creal(R),cimag(R));
	float complex A=4+5*I;
	float complex B=2+3*I;
	float complex Q=(2+5*I)/A;
	printf("Q: %g + %gi (%f + %fi) \n",creal(Q),cimag(Q),creal(Q),cimag(Q));
	float complex S=B*Q;
	printf("S: %g + %gi (%f + %fi) \n",creal(S),cimag(S),creal(S),cimag(S));
	R=R-S;
	printf("R: %g + %gi (%f + %fi) \n",creal(R),cimag(R),creal(R),cimag(R));
	Q=R/A;
	printf("Q: %g + %gi (%f + %fi) \n",creal(Q),cimag(Q),creal(Q),cimag(Q));
	S=A*Q;
	printf("S: %g + %gi (%f + %fi) \n",creal(S),cimag(S),creal(S),cimag(S));
	R=R-S;
	printf("R: %g + %gi (%f + %fi) \n",creal(R),cimag(R),creal(R),cimag(R));
	return 0;
}
J'obtiens en retour ceci:
R: 4 + 1i (4.000000 + 1.000000i)
Q: 0.804878 + 0.243902i (0.804878 + 0.243902i)
S: 0.878049 + 2.90244i (0.878049 + 2.902439i)
R: 3.12195 + -1.90244i (3.121951 + -1.902439i)
Q: 0.0725758 + -0.56633i (0.072576 + -0.566330i)
S: 3.12195 + -1.90244i (3.121951 + -1.902439i)
R: 2.38419e-07 + 0i (0.000000 + 0.000000i)
Le problème se pose sur le denier résultat stocker en mémoire (la valeur R) qui est faux car il est censé valoir 0 or comme on peut le voir, si je demande l'affichage par un %g on obtient un nombre donc la machine a stocké une valeur différente de 0 en mémoire. Lorsque j'effectue cette enchaînement de calcule avec ma calculatrice, j'obtient bien 0.

Par conséquent a cause de ce petit problème de calcule effectué par la machine ma fonction de division euclidienne dans mon projet fait une boucle infini car le reste n'est jamais un polynôme de degré inférieur au diviseur marquant ainsi la fin de la division.

Je voudrais donc savoir pourquoi je rencontrait ce problème et comment le résoudre.
Pourquoi mon dernier nombre stocké n'est pas 0?
Je trouve cela bizarre que la machine ne simplifie pas le nombre car un float est censé avoir 6 chiffre après la virgule car il est sur 32bit (comme on le vois avec l'affichage avec %f) or ici mon nombre est 0.00000023..... il devrait donc se simplifier et devenir 0 car le float stocke normalement 6 chiffre après virgule et là le 7e chiffre après la virgule est inférieur à 5.

Ne devrais je pas passé sous du double afin d'augmenter la précision?
Cependant je rencontrerai de nouveau ce problème, certes moins souvent mais il reviendra à coup sur en fonction de mes polynômes rentrés. Pareil avec du long double.

je pense que la solution est de passé en double et donc du 64 bit car ma calculatrice arrive a effectuer ces opérations sans erreurs et elle a l'aire d'être sur du 64 bit (11 chiffres après virgule), mais j'aimerais des explications sur cette simplification effectuée.


Ce que je voudrais surtout savoir c'est le pourquoi du comment en faite, pourquoi la simplification par la machine ne se fait pas

Merci d'avance de vos réponse et des explications (que qui m’intéresse le plus).