snowball a écrit 168 commentaires

  • [^] # Re: Bon divertissement

    Posté par  (site web personnel) . En réponse au journal J'ai regardé Don't Look Up. Évalué à 3.

    Ce que je voulais dire c'est que je ne comprends pas l'intérêt de distribuer des bons ou mauvais points à telle ou telle personne qui sert un message qui dépasse sa propre personne. Quel est l'intérêt ?

    Je ne sais pas si X ou Y a les comportements les pires qui soient possibles (sic). Et est-ce vraiment le cas ? On a mesuré ? Et on s'en fiche non ? Je ne sais pas non plus si X ou Y a une conduite idéale la plupart du temps (sic). Est-ce vraiment le cas ? Et on s'en fiche non ?

    Et il habite où l'acteur principal charismatique qui va permettre de toucher des millions de spectateurs et qui est une blanche colombe écologique, qui n'est jamais monté sur un yacht, qui n'a jamais pris l'avion ?

    En fait, tous ces procès de personne, ça n'a pas d'intérêt sur le plan collectif. Je préfère imaginer les actions positives, ou à minima les prises de conscience que le film peut déclencher chez de nombreux (télé)spectateurs.

  • [^] # Re: Bon divertissement

    Posté par  (site web personnel) . En réponse au journal J'ai regardé Don't Look Up. Évalué à 8.

    C'est un peu le coup du "Greta est à 0% une écolo, car on l'a vue manger plus de 0% d'un mac do dans un train qui fonctionne à plus de 0% grâce au diesel. Elle est donc 100% une imposture. Je peux donc bien soulager ma conscience à 100% en agissant à 0% pour le climat").

    C'est beau le binaire.

    Sinon, le film (en tant que réalisation artistique) était franchement un plaisir à regarder malgré l'effet miroir affligeant qu'il m'a donné.

  • [^] # Re: Le lycée d'avant, c'est le collège de maintenant.

    Posté par  (site web personnel) . En réponse au journal Deux petits problèmes de math niveau lycée.. Évalué à 5.

    Aucune modélisation, elliptique, hyperbolique, ou je ne sais quoi ne pourra rendre compte de la réalité car cette réalité n'est pas donnée dans l'énoncé.

    On choisit donc la seule modélisation permettant de résoudre cet exercice en l'état des données de cet énoncé (qui n'est qu'un prétexte à faire de la géométrie euclidienne de niveau lycée).

    Si on voulait traiter le problème dans une autre géométrie, il manquerait des informations: la courbure est de combien ? Car elle va dépendre de l'altitude à laquelle se déplacent les trains. D'ailleurs, rien ne dit que les trains roulent à une altitude constante et si j'exagérais, on pourrait même questionner la différentiabilité de la variété sur laquelle se déplacent les trains :)

    Mais bon, j'imagine que la remarque était de l'ordre de la taquinerie :)

    PS
    Même si on modélise elliptiquement, en rajoutant à l'énoncé l'hypothèse que les trains se déplacent à altitude constante et altitude 0 par rapport au niveau de la mer (ce qu'on ne sait pas), les distances parcourues sont suffisamment faibles pour que l'écart avec le modèle euclidien ne soit pas mesurable avec un outil de précision millimétrique (on est même en dessous de 2,6 microns d'écart par km si je ne me suis pas trompé dans mes calculs)

  • [^] # Re: Le lycée d'avant, c'est le collège de maintenant.

    Posté par  (site web personnel) . En réponse au journal Deux petits problèmes de math niveau lycée.. Évalué à 2.

    Bonjour Pierre_Roc,
    Vous dites

    C'est d'ailleurs rigolo de constater que beaucoup de commentaires ont résolu les problèmes avec des notions qui dépassent très largement le strict nécessaire…

    Sachant que le problème des trains est euclidien, qu'appelez-vous précisément le "strict nécessaire" ?

  • [^] # Re: problème 2

    Posté par  (site web personnel) . En réponse au journal Deux petits problèmes de math niveau lycée.. Évalué à 3.

    Bonjour,
    Si je comprends bien ton raisonnement, la réponse ne dépendrait pas des moments où sont atteints les éloignements dont il est question dans l'énoncé.

    Je propose une solution détaillée :
    Titre de l'image
    Graphe de la distance entre les deux points (en ordonnée, en km) en fonction du temps (en abscisse, en heure).

    Titre de l'image

  • [^] # Re: Le texte a son importance !

    Posté par  (site web personnel) . En réponse au journal Deux petits problèmes de math niveau lycée.. Évalué à 1.

    Le raisonnement, basé sur la temporalité de l'énoncé, est sympa. Il faudrait cependant justifier mathématiquement pourquoi la fonction "distance entre les trains" est strictement croissante après 14h. Mais cette justification n'est pas si triviale qu'elle n'y paraît. A part des "on voit clairement que …", la mettre formellement en place est du même niveau de difficulté que de résoudre le problème.

  • # Quel sont les objectifs d'ISN ?

    Posté par  (site web personnel) . En réponse à la dépêche Apprentissage de la programmation dans les lycées (SNT/NSI) — la création d’exercices. Évalué à 4.

    À la lecture des commentaires, je pense que l'incompréhension mutuelle provient de l'absence de définition claire des attendus de cet enseignement.

    Que veut-on ?

    1) Que des ados apprennent à utiliser des technologies plus ou moins caduques / pertinentes sous prétexte qu'elles leur rappellent les appareils addictifs du quotidien ?

    2) Que les ados comprennent petit à petit les concepts informatiques utilisés par les objets qui finissent plus ou moins par contrôler leur vie ?

    Sachant que ces deux activités sont totalement différentes et terriblement chronophages, il est difficile de vouloir faire un peu les deux.

    Quand je lis le bulletin officiel décrivant le programme, quand j'écoute les vidéos de Gilles Dowek (https://youtu.be/8n7Z8fDKe3A) (un personnage central dans la conception d'ISN); je pense qu'il s'agit du point numéro 2. Donc j'aurai effectivement tendance à penser que le travail de Claude, même s'il part très probablement d'une bonne intention de sa part, est hors sujet voire contre productif.

    J'ajouterai que personnellement, les meilleures séances informatiques que j'ai eu l'occasion de mener avec des élèves/étudiants étaient des activités débranchées écrites en langage naturel.

    L'écran, l'interface, les couleurs etc ne concentrent pas les élèves sur des problématiques informatiques mais sur des aspects secondaires (l'IHM) qui, de toutes façons, constituent à elles seules un véritable métier ne répondant pas aux objectifs du 2).

    Penser qu'on va intéresser les élèves aux concepts informatiques sous prétexte que le résultat affiché a un joli rendu est une erreur qui n'augure rien de bon sur la pertinence du contenu qu'on enseigne.

    Enfin, concernant le fait qu'il faille évincer les maths de l'enseignement de l'informatique pour ne pas décourager des élèves de s'y lancer, je pense que c'est tromper les élèves sur la matière elle même. A moins bien sûr qu'on ne résume l'informatique à l'utilisation d'outils, à la conception d'IHM ou l'administration réseau.

  • [^] # 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é à 4. Dernière modification le 29 janvier 2018 à 14:14.

    C'est exactement ça ! L'API peut parfaitement prévenir l'utilisateur, à la compilation, que le nombre de digits demandé n'est pas suffisant pour garantir l'exactitude du calcul des taux et le client de l'API devra réviser ses exigences à l'instanciation de son type "monnaie".

    En gros: tu peux aller en valeur absolue jusqu'à 10 puissance 12 et une précision de 7 digits après la virgule sans problème (c'est largement suffisant pour assurer les exigences européennes de conversion de devises dont parlait Kantien). Tu peux même créer des pré et post conditions dans la fonction "round" pour être averti, par une levée d'exception, que tu demandes l'impossible. Jamais le flottant ne te permettra d'avoir ce niveau de contrôle puisqu'il mange tout ce qu'on lui donne sans broncher.

    Et même si on regarde sur le plan mathématique, une analyse rapide montre qu'il est absurde d'utiliser un type decimal flottant codé en hard pour répondre au problème de la représentation de valeurs monétaires. Je m'explique:

    • on se confronte au phénomène de "cancellation". C'est à dire que si u=10^{14} et v=10^{-4} alors (u+v)-u perd quasiment tous ses chiffres significatifs et donc si on multiplie derrière par un entier assez grand, on obtiendra (silencieusement !!) quelque chose de complètement faux. Rien de pire que les erreurs silencieuses (donc détectables uniquement quand la catastrophe s'est produite)
    • si on note e le nombre de bits occupés par l'exposant dans la représentation machine du flottant (disons sur 64 bits), on voit qu'on n'utilise qu'un tout petit nombre valeurs possibles codées par les e bits (disons 16 pour fixer les idées). C'est à dire que sur les 2^{64} valeurs possibles du flottant décimal, seules environ un 64ème de ces valeurs sont utiles. En virgule fixe, on utilise vraiment les 2^{64} valeurs possibles. Cette perte d'informations montre à elle seule que le flottant n'est pas adapté à la situation dont on parle.
    • un dernier avantage concernant les perfs: la virgule fixe c'est de la gestion d'addition/soustraction d'entiers dans le backend FPU. C'est donc bien plus efficace que de manipuler du float au niveau FPU (2 voire 6 fois plus rapide en moyenne suivant le FPU utilisé).

    A quel problème informatique répond le concept de virgule fixe ? Réponse: il a été fait spécialement pour gérer un nombre fini de points (de façon exacte) uniformément répartis dans un intervalle borné; typiquement… une monnaie :)

  • [^] # 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é à 4.

    Intéressant Xavier ! Je la connaissais pas cette politique d'arrondi pour les caisses électroniques :

    Ainsi, si le montant total du ticket de caisse se termine par 0,01 ou 0,02, il sera arrondi à 0 centime. Si le montant se termine par 0,03 ou 0,04 ou 0,05 ou 0,06 ou 0,07, il sera arrondi à 0,5 centimes. Enfin, le montant se terminant par 0,08 ou 0,09 sera arrondi à 0,10 centimes.

    Ce passage concernant la gestion des arrondis par la machine de caisse confirme bien qu'il n'existe aucune API toute faite permettant de pratiquer la politique d'arrondi et que le programmeur ne peut se dispenser de coder lui même l'arrondi.

    Une API de haut niveau pour gérer ce problème consiste à faire un type générique avec pour paramètres un type delta (virgule fixe) ET la fonction d'arrondi ad hoc.
    Exemple:

    -- le fichier de spécifications
    generic type Decimal is delta <>; -- on fournira, à l'instantiation du package, la précision et la plage
    with function my_round (float_value : Long_Float) return Decimal; -- et on lui fournit une politique d'arrondi (cf le PS3 en bas de mon post au sujet de l'encapsulation possible du type long_float)
    
    package my_general_money is -- on fournit au client un outil pour calculer des taux respectant scrupuleusement la politique d'arrondi fournie par my_round
      function "*" (rate : Long_Float; value : Decimal) return Decimal;
    end my_general_money;
    
    -- le fichier d'implantation de la fonction "*" 
    package body my_general_money is
     is  
      function "*" (rate : Long_Float; value : Decimal) return Decimal is
    ( my_round (rate * Long_Float (value)));
    end my_general_money;
    
    -- Voilà ! fini ! On dispose à ce stade d'une API générique complète pour gérer une monnaie quelconque  liée à une politique d'arrondi donnée
    -- Un programme principal dans un troisième fichier pour tester ce module sur l'euro. Voilà ce qui se passe côté utilisateur de ce module:
    
    with ada.text_io; use ada.text_io; -- entrée sorties
    with my_general_money; -- notre API complète pour créer une monnaie
    
    procedure main is
    -- On instancie une monnaie à nous (virgule fixe)
      type Euro is delta 0.001 range -10.0**10 .. 10.0**10;
    -- On se donne une politique d'arrondi (ici l'arrondi par défaut fourni par Ada
      function round_euro (lf : Long_Float) return Euro is (Euro (lf)); 
    -- on instancie un package pour ajouter à notre Euro une politique d'application d'un taux
      package Euros is new my_general_money (Euro, round_euro); use Euros;
    -- Voilà ce que le programmeur a à faire: 3 lignes pour décrire ses contraintes et sa politique d'arrondi. Il a maintenant tout pour jouer avec sa monnaie
      e1 : Euro := 3.0; -- expression littérale très naturelle pour le programmeur
      e2 : Euro; 
      rate : Long_Float := 2.0/3.0; -- une baisse de 33.333.... pourcents
    -- rappelons qu'un taux n'est pas une valeur monétaire mais (idéalement) un réel.
    begin
      e2 := rate * e1;
      put_line (e2'img);  -- affichera exactement 2.000 (c'est à dire que la sortie tient compte de la précision en vigueur sans rien avoir à faire
    end Main;

    Ce qu'on gagne à faire ça:

    • On dispose d'une API complète parfaitement encapsulée de haut niveau où le programmeur fournit simplement sa politique d'arrondi (on peut même en mettre une par défaut si on veut, ou même lui filer dans l'API une dizaine de modèles codées par celui écrit l'API une fois pour toutes).
    • Le code reflète exactement la nature du problème mathématique. Le code contient du sens et donc:
    • Le programmeur (client de l'API) est obligé de faire correctement les choses: il est obligé de faire la distinction entre les types des objets qu'il manipule. Il ne peut par exemple pas écrire un Euro * un Euro. Mais il peut bien évidemment écrire un entier * un Euro,ou un Euro +/- un Euro et il est certain que le calcul sera rigoureusement exact. Dans cette approche on peut écrire ce qui a du sens, on ne peut pas écrire ce qui n'en a aucun dans le cadre de l'API fournie.
    • Il est assuré qu'au moindre calcul hors plage de sa monnaie, une exception sera levée (contrairement au décimal flottant qui serait silencieux: danger !!!)
    • Il ne peut pas écrire à la main e := 2.0001 sans se prendre une erreur du compilateur qui lui signifie que la valeur entrée est stupide puisqu'elle exige une précision supérieure à celle qu'il a exigée dans son type
    • Il n'a rien eu à coder à part sa fonction d'arrondi si elle n'est pas standard (c'est bien le minimum légal, sans jeu de mot :) )
    • Chaque fois qu'un changement de politique d'arrondi se produit, il n'a qu'une seule fonction à coder, il n'a rien d'autre à toucher nulle part dans le code.
    • On n'a même pas besoin de coder les entrées/sorties: le formatage est géré tout seul parce que ada écrit correctement de la virgule fixe et ça rappelle, à l'affichage, le nombre de chiffres correspondant à la précision souhaitée.
    • Le client de l'API n'a même pas à faire appel lui même à sa fonction d'arrondi. C'est l'API qui le fait pour lui.
    • Pour le calcul de taux, que le long_float soit binaire ou décimal n'a aucune importance concernant l'exactitude des résultats : on obtiendra toujours la même chose à la fin avec l'un ou l'autre contrairement à ce qui a été insinué plusieurs fois dans ce fil. Le programmeur n'a même pas à savoir comment c'est géré par Ada: Ada lui garantit simplement que les specs sont respectées.

    Ceci répond à tous les souhaits exprimés par Dring (y compris les conversions entre devises); Une API de type Decimal (qui a été mentionnée comme solution pour les problèmes de Dring) ne pourra jamais bénéficier de tous ces avantages car trop silencieuse / permissive (même sémantiquement on peut y écrire Decimal("0.1") fois Decimal("0.000001") sans se prendre le moindre warning puisque Python n'a aucune indication dans le code du 'sens' qu'il faut donner à ces expressions ; Et puis, pour le programmeur, comme le disait Dring, c'est franchement pas agréable de se traîner à chaque calcul l'instanciation d'une classe à partir de chaînes de caractères. Côté client, difficile de faire plus fluide, plus naturel ou plus précis.

    PS1
    J'ai mis plus de temps à écrire le texte de ce commentaire qu'à coder l'API (qui prend 5mn).
    PS2
    J'espère que ce post aura clarifié les incompréhensions réciproques.
    PS3
    Si on veut laisser au client de l'API la possibilité de coder son arrondi on ne peut lui cacher le long_float. Mais si on lui fournit une centaine de politiques d'arrondi directement dans notre API, ou si on lui code selon ses souhaits, on pourra même lui cacher le long_float.

  • [^] # 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é à 2.

    C'est des règles pour les paiements en liquide, ça ne nous concerne pas

    Regarde ce que raconte IBM sur différents modèles d'arrondis : https://www.ibm.com/support/knowledgecenter/fr/SSZLC2_7.0.0/com.ibm.commerce.management-center.doc/concepts/cpiactrounding.htm Le tableau présenté rassemble 11 exemples de modèles qui peuvent se présenter quand on manipule de la monnaie. Il n'y a pas d'API toute faite pour les arrondis dans un quelconque module généraliste décimal et le flottant décimal ne sera d'aucune utilité pour les gérer.

    J'essaye juste de te dire que l'implantation en virgule fixe répond à toutes les exigences de ce que veut faire Dring (c'est normal, ça sert à ça):

    • conversions entre devises avec garantie de respect de la norme de précision en vigueur en Europe.
    • addition/soustraction et multiplication entier * type D exacte dans les limites de la plage de représentation (10 puissance 12 si besoin).
    • alertes à la compilation en cas d'écritures grossièrement fausses ou exceptions à l'exécution
    • application de taux flottants à des éléments de type D avec garantie du respect de la précision pour des taux compris entre 0,001 et 1000 (on peut pousser au besoin)

    J'essaye d'expliquer que, concernant le flottant décimal:

    • il n'apporte absolument rien à l'affaire (rien que pour les conversions entre devises, tu n'as quasiment jamais un rapport décimal pour passer d'une devise à l'autre dans les deux sens). Tu as argumenté pendant plusieurs posts en sa faveur et je n'ai toujours pas compris ce que ça pouvait bien apporter.

    • il est, comme tout flottant, trop silencieux donc potentiellement dangereux (les erreurs silencieuses, y a rien de pire). Et c'était un besoin de Dring.

    Tu évoques la nécessité de disposer d'une API complète, mais la virgule fixe propose tout ce qu'il faut (sauf qu'elle ne peut pas décider à ta place de ta gestion des arrondis). Je ne dis rien de plus.

    Voilà, je pense comme toi que ça ne sert plus à grand chose de continuer et qu'on a fait le tour. De mon côté j'ai apprécié, j'ai appris plein de choses, désolé si ce n'était pas le cas pour toi.

  • [^] # 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é à 1.

    Complément:

    Pour des conversions de devises propres et sûres respectant scrupuleusement la norme européenne:

      type change is delta 10.0**(-7) range 0.000_1 .. 1000.0;
    
      function Convert (from : change; target : change; value : dec) return dec is
      ((long_float (target)/long_float (from)) * value);
    1. On voit ici que le fait que long_float soit binaire ou décimal n'apporte rien: le résultat donné sera juste dans les deux cas (car la précision sur le premier quotient
    2. On ajoute volontairement un type change obligeant le programmeur à respecter les bonnes pratiques et pas à faire n'importe quoi dans n'importe quel ordre avec des floats. On ajoute aussi des garde fou (impossibilité de diviser par zéro, et surtout on est explicite. si des débordements on lieu, il y aura levée d'exception (rien n'est silencieux).
    3. On peut de plus garantir que Convert donne le bon résultat (car max_change/min_change est majoré par 1 million et donc le quotient flottant ne fait perdre qu'une précision de 6 digits au long_float (17 chiffres significatifs) et laisse de quoi garantir que round fera exactement ce qu'elle doit faire). C'est là tout l'avantage de mettre des contraintes sur les types et de ne pas prier à chaque fois qu'on manipule des floats sans aucun contrôle.
  • [^] # 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é à 2.

    Je m'arrête là pour le fond et je conteste cette partie de la spécification que tu proposes (sinon tout le reste s'ensuit bien, comme il se doit, sur le plan mathématique : je conteste ta première prémisse). […devises différentes à prendre en compte]

    suivi de

    Wherever these conversion rates are used, they will have to be applied exactly,

    Si tu dois faire des conversion entre des € et une devise A où 1,000_000 € = 1,500_000 A, il t'apporte quoi le flottant décimal ? Il ne fera pas mieux que le flottant binaire pour la conversion de A vers €.
    Mais de toute façon, ça ne pose aucun problème: tu gères tout dans une monnaie (disons l'euro avec virgule fixe) et convertir d'une devise à l'autre avec 6 décimales exactes comme exigé ne pose pas le moindre problème (mon arrondi au centime en Ada n'était qu'un exemple et rien n'empêche d'aller chercher 6 décimales exactes).

    Il n'y a aucune mauvaise foi, c'est bien un problème d'API. Un programmeur qui a besoin de décimaux veut pouvoir écrire : arrondi moi ce nombre à la deuxième décimal selon telle règle d'arrondis. Autrement dit, il veut quelque chose du genre : Decimal.(round 2 (dec "0.70" * dec "1.05"))

    Et comment tu lui dis à Python comment il doit arrondir sachant que les règles d'arrondi tu en as quasiment une par pays ! cf https://en.wikipedia.org/wiki/Cash_rounding
    Python ne peut pas connaître toutes ces règles ! L'arrondi ne sera jamais out-of-the-box. La norme IEEE754 (décimale ou non) ne proposera jamais quoique ce soit pour répondre à la diversité de ces règles (et encore heureux !). Tu as une fonction qui permet de faire round ("irlande",4.6789987,2) ?

    Toi ce que tu dis, c'est que l'on peut prendre t = float et définir round de façon à ce qu'il se comporte correctement. Ce à quoi je t'ai répondu : personne ne l'a jamais nié, mais le programmeur ne veut pas avoir à faire ça à la main,

    Qu'il pleure ou qu'il gémisse, il devra de toute façon le faire car il n'a pas le choix, vu qu'il y a plus de règles d'arrondis dans le monde qu'il n'y a de modes d'arrondi définis par la norme IEEE754 décimale (remarque au passage que cette norme ne propose rien de plus que la norme classique en terme de nombre de modes d'arrondis: 3 modes différents qui ne portent de toute façon que sur le dernier ulp. De toute façon le décimal ne propose rien pour l'arrondi à la mode irlandaise ou norvégienne etc.

    Pour synthétiser:

    1. Pour les conversions de devise exactes: le flottant décimal n'apporte absolument rien par rapport au flottant binaire (exemple 1€ <---> 1,5A ça te sert à quoi le flottant décimal pour passer de A à € ?). De toute façon le flottant binaire suffit amplement pour appliquer scrupuleusement l'exactitude au millionième près.
    2. Les règles d'arrondi sont tellement diverses (presque une par pays !) qu'aucune norme ne pourra dispenser le programmeur en économat de produire le code ad hoc.
    3. La seule chose que doit faire le programmeur c'est de coder cet arrondi: tout le reste c'est out of the box en virgule fixe (normal, ça a été fait pour ça).
    4. Si tu utilises du flottant ça peut devenir la foire à la saucisse dans le code si le programmeur "ne veut pas trop se prendre la tête". Au contraire, l'emploi de la virgule fixe façon Ada, empêche le programmeur en amont de faire n'importe quoi: les erreurs grossières ne doivent jamais rester silencieuses (à la compilation, le flottant sera toujours silencieux, au runtime idem, à moins de taper dans du 10 puissance 300 et des brouettes.
    5. Rien de de que dit Muller dans le lien que tu me donnes ne contredit tout cela (ou alors j'ai raté un passage). Le flottant décimal a des utilisations pratiques mais pour les besoins de Dring, ça n'a aucun intérêt.
  • [^] # 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é à 2.

    Sommaire

    Sur le fond

    Virgule fixe / flottant binaire / flottant décimal ? Quel choix quand on veut représenter des valeurs monétaires en machine ?

    Appelons D le type censé représenter notre monnaie. Qu'attendons nous de lui ?

    1. D doit pouvoir représenter de façon exacte les nombres de la forme k/100 où k est un entier compris dans un intervalle fixé borné (ici on pourrait se contenter de k inférieur à 1 million de milliards soit 10 puissance 15).

    2. On doit pouvoir, de façon exacte, additionner / soustraire dans D.

    3. Comme on ne multiplie pas des valeurs de D entre elles mais qu'on veut pouvoir prendre des fractions de D il nous faut pouvoir multiplier un float par un élément de D et obtenir un élément de D. On doit donc disposer en particulier d'une fonction d'arrondi de float vers D qui respecte scrupuleusement des règles fixées (éventuellement plus complexes que les 3 modes que propose les différentes normes IEEE754 décimal ou binaire). Celle-ci devra donc être codée par le programmeur en fonction des spécifications.

    4. Il serait bon, bien que non indispensable, que le programmeur puisse entrer des expressions littérales usuelles directement dans D et surtout, que le compilateur empêche des écritures qui sortent des attendus ci-dessus, et oblige le cas échéant au programmeur de forcer les choses par du casting explicite.

    Pour faire matheux, D doit donc posséder une structure (exacte) de Z-module et représenter des valeurs uniformément réparties d'un intervalle fixé (dont le diamètre ne dépasse pas 10 puissance 15). Cette description n'est pas celle des flottants (ulp variable, dynamique inutile pour représenter de la monnaie), par contre c'est exactement la description de la virgule fixe qui a été conçue spécialement pour ça.

    Une implantation rapide en Ada pour éclairer davantage

    with ada.text_io; use  ada.text_io; 
    
    procedure my_dec is
      --  Déclaration de notre type stockant la monnaie
      type dec is delta 0.01 range -10.00**16 .. 10.00**16;
      for dec'small use 0.01;
    
      -- Description des règles d'arrondi, à modifier en fonction des spécifications  
      -- Ici on choisit l'arrondi au centime couramment utilisé évoqué dans le lien que tu as donné
      function round (u : long_float) return dec is
        function rounding_positive (u : long_float) return dec is
          d2  : dec := dec (100.0 * u); 
          d1  : dec := 100 * dec (u);
        begin
          return (if d2 -d1 >= 0.5 then 0.01 * d1 + dec'small else 0.01 * d1);
        end rounding_positive;
      begin
        return (if u>=0.0 then rounding_positive (u) else - rounding_positive (-u));
      end round; 
    
      -- On ajoute une opération permettant d'appliquer des taux (flottants) à notre monnaie
      function "*" ( rate : long_float; d : dec) return dec is (round (rate * long_float (d)));
    
      value : dec := 100.0;
      d : dec := (1.0 / 3.0) * value;
    begin
      put_line (d'img);  -- affiche 33.33 comme attendu
      d := (2.0/3.0) * value;
      put_line (d'img); -- affiche 66.67 comme attendu
      d := 1.05* dec (0.7);
      put_line (d'img); -- affiiche 0.74 comme attendu
      d := 0.01;
      while d <= 0.05 loop -- fait exactement 6 tours comme attendu 
        put_line (d'img);
        d := d + 0.01;
      end loop;
      d := round (0.004); 
      put_line (d'img); -- affiche 0.00 comme attendu
      d := round (0.005); -- affiche 0.01 comme attendu
      put_line (d'img);
      d := 10_000_000_000_000_000.0 + 0.01;
      put_line (d'img);  -- affiche 10_000_000_000_000_000.01 comme attendu
      d := 0.001;  -- provoque une erreur de compilation explicite
      d := 
    end my_dec;

    Trois commentaires

    1. ma fonction d'arrondi correspond à une spécification particulière, mais le programmeur ne pourra faire l'économie d'écrire la fonction correspondant aux politiques d'arrondi qu'il a à respecter. C'est le seul moment où j'ai écrit du code "compliqué". Tout le reste est out-of-the-box et en terme d'API, c'est plus efficace (car plus safe au niveau code) que d'utiliser du flottant qui sera, par nature silencieux sur des écritures absurdes et qui sera également silencieux quand on dépasse les bornes de l'intervalle (alors qu'il faudrait soit empêcher la compilation le cas échéant, soit lancer des exceptions à l'exécution). Ce sont des exigences qu'un programmeur est en droit d'attendre dans l'économat et que ne lui fournit pas le flottant (binaire ou décimale).
    2. dans la fonction d'arrondi on peut ajouter des post et pré conditions si on veut rajouter la vérification que la fonction fait bien qu'elle doit faire et que ses arguments soient dans des bornes acceptables (cf https://en.wikibooks.org/wiki/Ada_Programming/Contract_Based_Programming )
    3. Les exemples que j'ai donnés montrent, que sans le moindre effort, on peut répondre aux problèmes auxquels n'est censé répondre que le flottant décimal (en tout cas c'est ce qu'on pourrait croire en lisant le lien (IBM) que tu as donné.

    Sur la forme

    Tu me cites:

    Quand on a décidé de mal arrondir, c'est sûr, on arrondit mal, ça on est d'accord.

    ce qui me semble être une évidence et refléter ce que tu as fait en python. Puis tu me réponds:

    Non ce qui est reproché aux flottants binaires sont leur API si on veut travailler avec du décimal.

    Mauvaise foi ? On était parti d'erreurs factuelles sur le site d'IBM que tu as mentionné concernant le calcul de 0.70 x 1.05. Ils font deux erreurs: la première sur le résultat du calcul en utilisant des "double". L'autre en arrondissant au centième sans tenir compte du chiffre des millièmes en sous-entendant que ça serait la faute du binaire flottant (!!!!) (La preuve que c'est du grand n'importe quoi est dans mon petit programme ci-dessus: aucun problème à arrondir correctement) et là tu me redis un "Non" (un non à quoi au juste ?) et tu embrayes en disant que finalement c'est un problème d'API !

    Que l'on puisse présenter un type abstrait, représenté de manière sous-jacente via le type float primitf (en binaire) d'un langage donné, qui se comporte comme des décimaux : personne ne le nie. Mais à ce compte là, il te suffit de [tout reconstruire à la main]

    Le programme ci-dessus te montre qu'on est très loin de cette caricature tu ne crois pas ?
    J'écris ensuite qu'il faut spécifier pleinement et qu'alors on fait facilement ce qu'on a à faire et tu réponds:

    Oui et c'est ce qu'a fait l'auteur du site en question, à savoir Mike Cowlishaw, en rédigeant la norme IEEE-754 pour les décimaux flottants.

    Je parlais de ce que veut l'utilisateur (en économat en l'occurrence). Je ne parle pas de celui qui pond une norme générale (qui d'ailleurs ne fournira pas forcément la bonne fonction d'arrondi out of the box au banquier). J'imagine bien que Mike Cowlishaw a fait ce qu'il avait à faire quand il a rédigé sa norme. D'autre part, les arrondis gérés par sa norme ne portent pas sur la deuxième décimale qui intéresse le banquier mais sur le dernier ulp (donc il faudra coder la fonction d'arrondi un peu comme je l'ai fait probablement)

    Effectivement, c'est bien ce qu'il me semblait : tu n'as aucune idée des besoins et des attentes de ce domaine métier. ;-)

    Peut-être pourrais-tu nous rappeler précisément ces besoins. J'ai l'impression que ni toi ni moi ne les connaissons précisément. Je fais ce que je peux en raisonnant mais si tu as des choses plus précises n'hésite pas à en faire part, c'est toujours intéressant.

    Je ne dis pas du tout que le flottant décimal est inutile (j'imagine bien qu'il y a des cas d'utilisation où c'est pratique), je dis qu'il ne répond pas aux besoins de Dring ce qui est très différent.

  • [^] # 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é à 1. Dernière modification le 26 janvier 2018 à 20:26.

    Non, ce n'est pas cela qu'il cherche à illustrer mais l'arrondi d'une opération à la deuxième décimale.

    Quand on a décidé de mal arrondir, c'est sûr, on arrondit mal, ça on est d'accord. Si l'on veut arrondir correctement à 0.01 près, on fait le calcul à 0.001 près pour décider si on doit aller au dessus ou en dessous pour l'arrondi au centième. C'est d'ailleurs ce que font les calculatrices (avec leurs chiffres cachés, et c'est aussi ce que font les processeurs avec les bits supplémentaires permettant de faire les arrondis (défaut, excès, au plus près)). Quand on fait cela, il n'y a aucun problème avec les floats binaires.

    Sur le site que tu donnes il y a d'autres choses étranges.

    #include <iostream>
    using namespace std;
    
    int main()
    {double x = 1.05, y = 0.7, r1, r2 = 0.735;
      r1 = x * y;
      cout << r1 == r2 <<endl; // Va afficher True 
      return 0;
    }

    Où est le problème ? Quand bien même on arriverait à 0.7349999[…], il n'y aurait pas de problème non plus: l'arrondi traité comme il faut donne ce que veut le banquier. Suivant la convention en vigueur, on peut donc parfaitement décider si l'on doit renvoyer, au centièmes près, 0.73 (par défaut) ou 0.74 (par excès). Le float binaire donnerait tout aussi bien le bon résultat si r1 était le résultat d'un quotient comme le sont la plupart des taux manipulés dans l'économat. Je n'arrive pas du tout à comprendre ce que donne le float décimal dans ce genre de cas.

    Non, les taux de taxes et les taux de change sont fournis en décimal

    Il n'y a pas que ce genre de taux quand on fait de l'économat. Certains taux peuvent résulter d'un quotient (c'est même souvent le cas non ?).

    […] doivent pouvoir être représentés de manière exacte dans le type.

    Et pourquoi donc ? Si tu as une valeur approchée à 10^{-17} de la valeur finale, il n'y a aucun problème à donner un arrondi qui respecte les spécifications imposées en sortie.

    Chacun des exemples donnés sur http://speleotrove.com/decimal/decifaq1.html#inexact se traite sans aucun problème sans utiliser le moindre flottant décimal. Si tu spécifies ce que tu veux, tu peux faire une fonction de deux lignes qui renverra exactement ce qu'est censé recevoir l'utilisateur.

    Pour ce qui est des besoins des Dring, il a surtout fait mention du langage COBOL qui utilise des flottants[…]

    Oui et aussi de la virgule fixe dont les spécifications sont suivies à la lettre par Ada. Comme Dring voulait des alertes compilo en cas de "problème", il fallait en passer par la virgule fixe (le flottant étant silencieux par nature sur la plupart des opérations posant problème).

    Voilà comment je comprends le problème concernant la monnaie:

    En entrée, on reçoit du décimal x à 10^{-2} près (appelons ce type D).
    En sortie on veut du décimal y à 10^{-2} près.
    Entre les deux, on a des opérations donnant un résultat f(x), qui en général, ne sera pas nécessairement y. Ce qu'on veut c'est arrondir f(x) pour obtenir le y désiré. Je ne pense pas que l'utilisation du flottant décimal apporte quoi que ce soit de plus dans ce type d'application que le flottant binaire. En tout cas, je n'ai pas encore vu de contre-exemple et je ne vois pas trop (à part utiliser des types n'utilisant pas la même taille mémoire).

  • [^] # 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é à 2.

    Un autre point que je trouve étrange dans le lien que tu as donné (http://speleotrove.com/decimal/decifaq1.html#inexact). Je cite le passage:

    Using double binary floating-point, the result of 0.70 x 1.05 is 0.73499999999999998667732370449812151491641998291015625; the result should have been 0.735 (which would be rounded up to $0.74) but instead the rounded result would be $0.73.

    Ils veulent le bon arrondi au centième et ils s'y prennent bizarrement je trouve. Le float qu'ils obtiennent 0.734999[…] s'arrondit au millième le plus proche en 0.735 sans aucun soucis. On applique alors la convention bancaire et on obtient bien 0.74. Ils font ça dans tous leurs exemples et argumentent ainsi en faveur du décimal flottant.

    En plus ils ne mentionnent pas que la plupart du temps, les taux proviennent du résultat d'un quotient (\Delta y / \Delta x) et donc ne se stocke quasiment jamais de façon exacte (dans quelque base que ce soit).

  • [^] # 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é à 1. Dernière modification le 26 janvier 2018 à 16:18.

    Il y a une raison à ton obsession pour le décimal en virgule fixe et la virgule flottante uniquement en binaire ?

    Par exemple parce que Dring a émis le souhait de disposer d'un type où le compilateur le prévient d'opérations qui pourraient poser problème. A part les cas d'overflow, un type décimal flottant ne répond pas à sa demande alors que la virgule fixe le fait.

    Par contre, il y a quelque chose qui m'échappe. Autant je comprends qu'un type flottant décimal réponde parfaitement à un problème du genre : appliquer un taux décimal à un nombre décimal sans perte de précision (sauf si dépassement de la taille de la mantisse); autant je ne vois que très peu de cas où cette situation arrive concrètement puisque les taux qu'on manipule sont presque toujours calculés à partir de quotients et donc sont très rarement décimaux.

    Du coup, les seuls cas intéressants pour le flottant décimal sont les cas où le taux provient d'une saisie décimale fournie par l'utilisateur. C'est ce genre d'exemple fourni par le lien que tu as donné où effectivement on comprend l'intérêt du calcul décimal (flottant ou non) mais ce genre de cas n'est pas celui qui se présente le plus souvent dans l'économat.

    C'est pour ça que je demandais à Dring de fournir des exemples de code montrant précisément où résidaient ses problèmes.

  • [^] # 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é à 2.

    Du coup, est-ce que dans ce code la valeur du delta peut être une variable ?

    Tu peux faire des packages génériques (en gros des templates dans le monde C++) qui prennent en argument des types delta.
    Comme le nombre de devises existantes est assez limité, tu peux déclarer si tu veux , par exemple une centaine de devises différentes, dans un fichier, et les envoyer en paramètres dynamiquement à ton générique sans avoir à recoder toutes tes procédures ou fonctions et ça répond à ton souhait.

  • [^] # 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é à 2.

    A bien y réfléchir, je pense que ce que voudrait Dring c'est de la virgule fixe façon COBOL comme le propose Ada, qui permet de ranger directement dans des "décimaux" des littéraux et qui le prévienne dès qu'on sort des bornes ou qu'on descend en dessous du delta spécifié

    type my_dec is delta 0.01 range -100.0..100.0;

    Alors si tu écris

    s : my_dec;
    begin
       s := 0.001;
    [...]

    tu te prends une erreur de compilation 'value has extraneous low order digits'

    Si ça arrive au runtime, ça te lève une exception que tu peux intercepter et gérer.
    Idem si tu sors de la plage de my_dec. Si maintenant tu écris

    s,t : my_dec;
    begin
       s := 1.8;
       t := 0.2;
       s := 2.0 - s - t; -- L'affichage de s écrit 0.00 comme attendu dans son domaine d'application
    [...]
  • [^] # 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é à 1.

    Pour un flottant décimal comme évoqué dans ton lien, que va provoquer l'affectation x=10^{10}+0.01 sinon de l'absorption ? (un exposant augmenté de 1 multiplie l' ulp par 10 ). Alors bien évidemment, en augmentant la taille de la mantisse on peut, dans la plupart des cas, éviter ce genre de situation. Mais est-ce la bonne approche ?

    Dans le contexte donné par ton lien, ce dont on a besoin, c'est de pouvoir représenter avec un ulp constant (le centième), tous les nombres de la forme n 10^{-2} contenus dans un intervalle fixe (du genre $[-10{10};10{10}]). Le contexte est donc celui de la virgule fixe non ?

    Les langages qui proposent de la virgule fixe, l'implantent en utilisant des floats en arrière boutique. C'est pourquoi je disais que si les choses sont correctement spécifiées, on peut toujours faire avec les floats. Et bien évidemment, mieux vaut utiliser un langage qui fait de la virgule fixe out of the box (comme Ada avec des déclarations de type du genre:

     type my_decimal is delta 0.01 range -10_000_000_000 .. 10_000_000_000;

    PS
    Je ne sais pas si on s'est bien compris

  • [^] # 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 ?

  • [^] # 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é à 2.

    Comme dit Michaël, mes exemples avaient juste pour but de montrer que le langage ne peut décider à la place du programmeur comment arbitrer les arrondis.
    Si la spécification est complète, alors je ne vois pas en quoi le type float apporterait plus de problèmes que le type décimal.
    Pour y voir clair, peut être que tu pourrais nous donner un bout de code avec flottants et qui pose problème puis donner le même bout de code avec le type décimal que tu voudrais et pour lequel il n'y aurait plus de problème, indépendamment des entrées.

  • [^] # 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é à 2.

    La grande majorité des profs de math aurait-elle un problème avec le français ? :) :)

    Et oui, je suis d'accord avec toi, je parlais bien des programmeurs qui sont confrontés souvent aux problèmes de calcul avec des flottants. Je suis conscient que beaucoup de programmeurs font face à des problèmes tout aussi complexes (certainement plus complexes d'ailleurs) qui n'ont rien à voir avec IEEE754 (je peux te citer en exemple puisque je te connais irl :) )

  • [^] # 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é à 2.

    Espèce de jeunot va ! :)

  • [^] # 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é à 4.

    Tout à fait. Dans l'école où je bosse, j'ai monté de toute pièce un module d'enseignement où l'on traite de ces sujets délicats (je dis vraiment merci à deux amis ingénieurs qui m'ont convaincu que c'était important). Les retours des étudiants qui ont poursuivi leurs études sont assez éloquents: c'est un enseignement qu'ils jugent à posteriori indispensable.

  • [^] # 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.

    […] les programmeurs qui ne sont pas conscients de toutes les décisions à prendre lorsqu'on programme ce genre de calculs.

    Tu résumes en une phrase la nature un peu trollesque (involontairement je pense) de ces deux journaux qui parlent des flottants: on ne peut pas faire l'économie des maths dès qu'on veut parler de la représentation des nombres en machine. Ça a l'air évident, mais ça ne l'est pas pour tout le monde vu que beaucoup de programmeurs (la grande majorité ?) est fâchée avec ces concepts difficiles mais doit faire face au quotidien à des difficultés qui viennent justement de ce manque de compréhension fine des concepts.

    Quand je dis ça, j'ai bien conscience que ça peut "blesser" certains mais ce n'est absolument pas mon but. C'est un constat qui n'est absolument pas un jugement méprisant de ma part. Je précise car je sens parfois une certaine animosité contre ce genre de propos. Kantien avait cité un texte très juste sur l'autre fil pour parler de cet affrontement absurde entre "théorie et pratique" où la pratique (associée inconsciemment au pragmatisme et à la réalité) l'emporterait sur la théorie (associée inconsciemment au rêve ou à l'hypothétique). La pratique informatique ne peut, dans certains cas, passer outre la théorie (typiquement sur ce genre de sujet).

    Il est difficile pour beaucoup de comprendre que les mathématiques ont fait le tour de ces sujets et que l'implantation choisie par défaut dans la plupart des langages est le choix le plus judicieux, non par choix arbitraire, mais par démonstration que c'est ce qu'il y a de moins mauvais avec les machines dont on dispose.

    PS1
    Je suis franchement agréablement surpris par le niveau remarquable de beaucoup d'intervenants sur ce site (que ce soit sur le plan mathématique et/ou informatique). Mis à part un cas pathologique que chacun aura identifié, je découvre quasiment à chaque commentaire quelque chose auquel je n'avais pas pensé, soit sur le fond, soit sur la forme et c'est vraiment un plaisir.

    PS2
    Le système "d'auto-modération" des fils (karma, masque des commentaires horribles) participe à la bonne lecture du sujet du journal. Certains forums devraient en prendre de la graine :)