⌂ Programmation
Fiche 7 sur 13

Les nombres à virgule

Calculer avec des décimales, et afficher proprement un résultat.

Après cette fiche, vous saurez :

1Pourquoi un nouveau type

Jusqu'ici, toutes vos variables étaient des int : des nombres entiers. Ça suffit pour des points de vie ou un compteur.

Mais pas pour un prix, une note, une taille ou une moyenne.

int prix = 12.50;    // refusé
Erreur : impossible de convertir 'double' en 'int'

Il faut un autre type de boîte : double.

double prix = 12.50;
double taille = 1.75;
double moyenne = 13.5;

Attention

Dans le code, la virgule s'écrit avec un POINT.

double prix = 12.50;    // correct
double prix = 12,50;    // refusé

C'est déroutant, mais c'est la règle du langage.

À l'affichage, en revanche, le résultat sortira bien avec une virgule, comme chez nous. Vous écrivez un point, l'ordinateur affiche une virgule.

TypeContientExemple
intUn nombre entierint hp = 50;
doubleUn nombre à virguledouble prix = 12.50;

À retenir

Lequel choisir ? Posez-vous une question simple : est-ce que la moitié a un sens ?

2Le piège de la division

Vous l'avez rencontré à la fiche 5 : entre deux entiers, la division oublie ce qui suit la virgule.

Console.WriteLine(7 / 2);     // 3, et non 3,5

Maintenant que vous connaissez double, voici la solution. Il suffit qu'un seul des deux nombres soit à virgule.

Console.WriteLine(7 / 2);       // 3     faux
Console.WriteLine(7.0 / 2);     // 3,5   correct
Console.WriteLine(7 / 2.0);     // 3,5   correct

Avec des variables

int a = 7;
int b = 2;

Console.WriteLine(a / b);              // 3     -> deux int
Console.WriteLine(a / 2.0);            // 3,5   -> un double dans le calcul

double x = 7;
double y = 2;
Console.WriteLine(x / y);              // 3,5   -> deux double

Attention

Attention : déclarer le résultat en double ne suffit pas.

int a = 7;
int b = 2;

double resultat = a / b;
Console.WriteLine(resultat);   // 3, et non 3,5 !

Pourquoi ? Parce que le calcul a / b se fait d'abord, entre deux int. Il donne 3. Ce n'est qu'ensuite que le 3 est rangé dans la boîte double.

La décimale est perdue avant même d'arriver dans la boîte.

La solution : déclarez vos variables en double dès le départ.

À retenir

La règle à retenir : dès qu'un calcul doit donner des décimales, tout ce qui entre dans le calcul doit être en double.

3Afficher proprement

Un calcul en double donne parfois un résultat à rallonge.

double prixHT = 21.87;
double tva = prixHT * 0.21;

Console.WriteLine($"TVA : {tva}");
Ce que l'ordinateur affiche
TVA : 4,5927

Personne n'affiche une TVA avec quatre décimales. Pour n'en garder que deux, on ajoute :F2 à l'intérieur des accolades.

Console.WriteLine($"TVA : {tva:F2}");
Ce que l'ordinateur affiche
TVA : 4,59
FormatEffetExemple d'affichage
{x:F0}Aucune décimale5
{x:F1}Une décimale4,6
{x:F2}Deux décimales4,59
{x:F3}Trois décimales4,593

À retenir

Le F vient de l'anglais fixed : un nombre fixe de décimales.

Utilisez :F2 dès que vous affichez de l'argent. C'est le réflexe professionnel.

Attention

Le format change l'affichage, pas la valeur.

double tva = 4.5927;

Console.WriteLine($"{tva:F2}");    // affiche 4,59
Console.WriteLine(tva * 2);        // 9,1854  -> le calcul garde tout

:F2 ne coupe rien dans la boîte. Il ne change que ce qu'on montre.

Arrondir pour de bon

Si vous voulez vraiment modifier la valeur, il faut Math.Round.

double moyenne = 13.67;

Console.WriteLine(Math.Round(moyenne));      // 14
Console.WriteLine(Math.Round(moyenne, 1));   // 13,7

4Demander un nombre à virgule

Souvenez-vous de la fiche 6 : Console.ReadLine() donne toujours du texte, qu'il faut convertir.

Pour un int, on utilisait int.Parse. Pour un double, c'est double.Parse.

Console.Write("Prix du produit : ");
string reponse = Console.ReadLine();
double prix = double.Parse(reponse);

Console.WriteLine($"Avec TVA : {prix * 1.21:F2} euros");
Ce que l'ordinateur affiche
Prix du produit : 45,50
Avec TVA : 55,06 euros

Attention

À la saisie, l'utilisateur tape une VIRGULE.

C'est l'inverse du code. Dans votre programme, vous écrivez 45.50 avec un point. Mais celui qui utilise le programme tape 45,50 avec une virgule, parce que Windows est en configuration belge.

Si vous tapez un point à l'exécution, le programme plante. C'est normal, et c'est déroutant la première fois.

→Exercices

1Voir le piègeRecopier

Recopiez ce programme. Avant de le lancer, écrivez sur papier ce que vous attendez pour chaque ligne.

int a = 10;
int b = 4;
double c = 10;
double d = 4;

Console.WriteLine(a / b);
Console.WriteLine(c / d);
Console.WriteLine(a / 4.0);

double resultat = a / b;
Console.WriteLine(resultat);

Console.WriteLine($"{c / d:F2}");

Console.ReadKey();

Solution

Ce que l'ordinateur affiche
2
2,5
2,5
2
2,50

Ligne 1 : deux int, division entière. 10 / 4 = 2,5, mais on jette le 0,5. Résultat : 2.

Ligne 2 : deux double. Résultat correct : 2,5.

Ligne 3 : le 4.0 suffit à basculer le calcul. 2,5.

Ligne 4 : c'est le piège de la section 2. Le calcul a / b se fait entre deux int et donne 2. Le ranger dans un double ensuite ne récupère rien. Résultat : 2.

Ligne 5 : :F2 impose deux décimales, d'où 2,50 et non 2,5.

2Réparer le programmeModifier

Ce programme doit calculer la moyenne de trois notes. Il donne toujours un résultat faux. Recopiez-le, lancez-le, puis corrigez-le.

Console.Write("Note 1 : ");
int note1 = int.Parse(Console.ReadLine());

Console.Write("Note 2 : ");
int note2 = int.Parse(Console.ReadLine());

Console.Write("Note 3 : ");
int note3 = int.Parse(Console.ReadLine());

int moyenne = note1 + note2 + note3 / 3;

Console.WriteLine($"Moyenne : {moyenne}");

Console.ReadKey();

Aide : il y a trois problèmes. Testez avec 12, 15 et 14 — la moyenne doit valoir 13,67.

Solution

Les trois problèmes

  1. Les parenthèses manquent. Sans elles, seule note3 est divisée par 3.
  2. Les notes sont des int. Une note de 14,5 existe, et la division entre entiers perdra les décimales.
  3. La moyenne est un int. Même corrigé, elle tronquerait le résultat.

La version corrigée

Console.Write("Note 1 : ");
double note1 = double.Parse(Console.ReadLine());

Console.Write("Note 2 : ");
double note2 = double.Parse(Console.ReadLine());

Console.Write("Note 3 : ");
double note3 = double.Parse(Console.ReadLine());

double moyenne = (note1 + note2 + note3) / 3;

Console.WriteLine($"Moyenne : {moyenne:F2}");

Console.ReadKey();
Ce que l'ordinateur affiche
Note 1 : 12
Note 2 : 15
Note 3 : 14
Moyenne : 13,67

Le réflexe qui aurait attrapé l'erreur : calculer le résultat de tête avant de lancer. 12 + 15 + 14 = 41, divisé par 3 = 13,67. Si l'écran affiche autre chose, il y a un problème.

3La caisse du magasin, version complèteCréer

Reprenez la caisse de la fiche 6, mais avec de vrais prix.

  1. Demandez le nom du client.
  2. Demandez trois prix (avec décimales) et trois quantités (entières).
  3. Calculez le sous-total de chaque article, le total hors TVA, la TVA à 21 %, et le total à payer.
  4. Affichez un ticket avec tous les montants à deux décimales.

Attention aux types : un prix est un double, une quantité est un int.

Solution

string client;
double prix1, prix2, prix3;
int qte1, qte2, qte3;

Console.Write("Nom du client : ");
client = Console.ReadLine();

Console.Write("Prix article 1 : ");
prix1 = double.Parse(Console.ReadLine());
Console.Write("Quantité 1     : ");
qte1 = int.Parse(Console.ReadLine());

Console.Write("Prix article 2 : ");
prix2 = double.Parse(Console.ReadLine());
Console.Write("Quantité 2     : ");
qte2 = int.Parse(Console.ReadLine());

Console.Write("Prix article 3 : ");
prix3 = double.Parse(Console.ReadLine());
Console.Write("Quantité 3     : ");
qte3 = int.Parse(Console.ReadLine());

// Les calculs
double sousTotal1 = prix1 * qte1;
double sousTotal2 = prix2 * qte2;
double sousTotal3 = prix3 * qte3;

double totalHT = sousTotal1 + sousTotal2 + sousTotal3;
double tva = totalHT * 0.21;
double totalTTC = totalHT + tva;

Console.Clear();

Console.WriteLine("+-----------------------------------+");
Console.WriteLine("               TICKET");
Console.WriteLine("+-----------------------------------+");
Console.WriteLine($"  Client : {client}");
Console.WriteLine();
Console.WriteLine($"  {qte1} x {prix1:F2}  =  {sousTotal1:F2} euros");
Console.WriteLine($"  {qte2} x {prix2:F2}  =  {sousTotal2:F2} euros");
Console.WriteLine($"  {qte3} x {prix3:F2}  =  {sousTotal3:F2} euros");
Console.WriteLine();
Console.WriteLine($"  Total HT   : {totalHT:F2} euros");
Console.WriteLine($"  TVA 21 %   : {tva:F2} euros");
Console.WriteLine($"  A PAYER    : {totalTTC:F2} euros");
Console.WriteLine("+-----------------------------------+");

Console.ReadKey();
Ce que l'ordinateur affiche
+-----------------------------------+
               TICKET
+-----------------------------------+
  Client : Sofia Martin

  3 x 15,50  =  46,50 euros
  2 x 4,20   =  8,40 euros
  1 x 29,99  =  29,99 euros

  Total HT   : 84,89 euros
  TVA 21 %   : 17,83 euros
  A PAYER    : 102,72 euros
+-----------------------------------+

Deux types dans le même programme, et c'est voulu. Le prix est un double parce qu'il a des centimes. La quantité est un int parce qu'on n'achète pas 2,5 articles.

Sans :F2, la TVA s'afficherait 17,8269. Essayez, pour voir la différence.

Vérification : 46,50 + 8,40 + 29,99 = 84,89. 21 % de 84,89 = 17,83. Total 102,72.

Je sais faire

Une case qui coince ? Relisez la partie concernée avant de passer à la fiche suivante.

← Fiche 6 Fiche 8 : Prendre une décision →