• [^] # Re: Il faut bien lire ce qu'on lit!

    Posté par (site web personnel) . En réponse au journal Le retour de la vengeance de la virgule flottante. Évalué à 3.

    Dans les années soixante, on avait un langage qui était conçu pour tout ça : le COBOL.

    C'est quoi "tout ça" ? C'est là qu'on ne peut plus te suivre. Quelles sont spécifications qui se cachent derrière ce "tout ça" ?

    Depuis, plus rien. Et on se retrouve à travailler avec des langages où il faut passer son temps à instancier une classe dès qu'on veut faire un calcul de base pour contrôler l'arrondi pour soit être cohérent avec les règles légales/réglementaires, soit éviter les centimes perdus.

    Aujourd'hui le langage Ada permet de déclarer des types répondant exactement aux spécifications du COBOL (cf https://en.wikibooks.org/wiki/Ada_Programming/Types/delta )
    Je précise dans ce lien l'endroit qui t'intéresse: https://i.imgur.com/FwGhVBW.png . Au passage, note que tout est "fully specified".

    Je veux que le langage (le compilateur ou l'interpréteur) me force à me poser la question dès que je risque de créer un problème d'arrondi ou de dépassement.

    C'est exactement ce que propose Ada.

    Exemple:

    with ada.text_io;use ada.text_io;
    procedure my_decimal is 
     type my_dec is delta 0.01 digits 6; -- 6 chiffres significatifs, précision au centième 
     s1, s2, s : my_dec;
    begin
     s1 := 1.8;
     s2 := 0.2;
     s := 2.0 - s1 - s2;
     put_line (s'img); -- affiche 0.00
     s1 := 2.0;
     s2 := 3.0;
     s := s1 / s2; 
     put_line (s'img); -- affiche 0.66 (conforme à la spec COBOL avec un écart entre réalité et résultat <0.01)
    end my_decimal;

    Ada gère la structure de \mathbb{Z} module (c'est à dire que tu peux parfaitement écrire un entier * un décimal)

    with ada.text_io;use ada.text_io;
    procedure my_decimal is 
     type my_dec is delta 0.01 digits 6; -- 6 chiffres significatifs, précision au centième 
     s : my_dec;
    begin
     s := 0.01;
     s := 10_000 * s;
     put_line (s'img); -- Affiche 100.00
    end my_decimal;

    Mais Ada te prévient à la compilation s'il ne peut être certain que tu veux vraiment manipuler des décimaux en te croyant dans un anneau plutôt qu'un \mathbb{Z}-module):

    with ada.text_io;use ada.text_io;
    procedure my_decimal is 
     type my_dec is delta 0.01 digits 6; -- 6 chiffres significatifs, précision au centième 
     s, s1 : my_dec;
    begin
     s := 0.01;
     s1 := 10.0;
     s := 10.0 * s * s1; -- (ligne 9) qui va provoquer une erreur à la compilation
     put_line (s'img);
    end my_decimal;

    Ne compile pas et te sort :
    my_decimal.adb:9:13: type cannot be determined from context
    my_decimal.adb:9:13: explicit conversion to result type required
    gprbuild: *** compilation phase failed

    Dernier point, la prévention ne se déroule pas seulement à la compilation, mais, par défaut, il y a un contrôle, au runtime, des contraintes de dépassements que tu peux évidemment traiter comme tu le veux par la gestion des exceptions ad hoc.

    Ne serait-ce pas ce que tu attends ?