Exercice : Nombres Complexes#
À faire
2025-2026
Extraire le code dans un fichier pour le compiler.
On rappelle qu’un nombre complexe est un nombre qui s’écrit \(a+ib\) où
\(a\) est appelé partie réelle et \(b\) partie imaginaire. Il faudra
systématiquement passer deux float
, pour passer un nombre complexe
en paramètre.
Attention, dans tout cet exercice, faire bien attention à quels sont les paramètres qui sont des résultats et quels sont ceux qui sont des données.
Définissez une procédure
saisie
qui demande à l’utilisateur d’entrer un nombre complexe, et qui a pour résultat le nombre complexe entré par l’utilisateur.BEGIN SOLUTION
void saisie(double &r, double &i) { cout << "Partie réelle : " << endl; cin >> r; cout << "Partie imaginaire : " << endl; cin >> i; }
END SOLUTION
Définissez une procédure
affiche
qui affiche un nombre complexe.BEGIN SOLUTION
void affiche(double r, double i) { if (i >= 0) cout << r << "+" << i << "i" << endl; else cout << r << "-" << -i << "i" << endl; }
END SOLUTION
Définissez une procédure
somme
qui calcule la somme de deux nombres complexes.BEGIN SOLUTION
void somme(double r1, double i1, double r2, double i2, double &sommer, double &sommei) { sommer = r1 + r2; sommei = i1 + i2; }
END SOLUTION
Définissez une procédure
produit
qui calcule le produit de deux nombres complexes. On rappelle que \((a+ib)\times(c+id) = (ac-bd)+i(ad+bc)\).BEGIN SOLUTION
void produit(double r1, double i1, double r2, double i2, double &prodr, double &prodi) { prodr = r1*r2 - i1*i2; prodi = i1*r2 + i2*r1; }
END SOLUTION
Définissez une fonction
norme_carre
qui renvoie le carré de la norme d’un nombre complexe. On rappelle que $\(|a+ib|^2 = a^2+b^2\,.\)$BEGIN SOLUTION
double norme_carree(double r, double i) { return r*r + i*i; }
END SOLUTION
Définissez une procédure
inverse
qui renvoie l’inverse d’un nombre complexe. On rappelle que $\({1\over a+ib} = {a-ib\over|a+ib|^2}\,.\)$BEGIN SOLUTION
void inverse(double r, double i, double &invr, double &invi) { double norme; norme = norme_carree(r, i); if (norme == 0) { cout << "Inverse de 0"; exit(1); } invr = r/norme; invi = -i/norme; }
END SOLUTION
Difficile : L’algorithme de calcul de la racine carrée fonctionne en général sur les nombres complexes \(z = a+ib\): la suite
\[u_0 := z, \qquad u_{n+1} := {u_n + z / u_n\over2}\]converge (presque toujours, voir la question suivante) vers une racine carrée de \(z\). Définissez une procédure
racine
qui calcule la racine carrée d’un nombre complexe. On considère que l’approximation \(u\) est correcte si $\({|u^2-z|\over|a|} < 10^{-6}\,, \qquad\hbox{c'est-à-dire si}\qquad {|u^2-z|^2\over|z|^2} < 10^{-12}\,.\)$BEGIN SOLUTION
double erreur(double ur, double ui, double ar, double ai) { double u2r, u2i; double sommer, sommei; produit(ur, ui, ur, ui, u2r, u2i); somme(u2r, u2i, -ar, -ai, sommer, sommei); return norme_carree(sommer, sommei) / norme_carree(ar, ai); } void racine_carree(double ar, double ai, double &raciner, double &racinei) { double unr, uni; double invr, invi; double prodr, prodi; double sommer, sommei; unr = ar; uni = ai; while (erreur(unr, uni, ar, ai) >= epsilon*epsilon) { inverse(unr, uni, invr, invi); produit(ar, ai, invr, invi, prodr, prodi); somme(unr, uni, prodr, prodi, sommer, sommei); unr = 1.0/2.0*sommer; uni = 1.0/2.0*sommei; } raciner = unr; racinei = uni; }
END SOLUTION
Difficile : En fait, la suite précédente ne converge pas dans le cas particulier où \(a\) est un réel négatif. On pourra dans ce cas choisir \(u_0 = a + i\epsilon\). Modifier le programme en conséquence.
BEGIN SOLUTION
if (ai == 0 && ar < 0) uni += epsilon;
END SOLUTION