Appelons D le type censé représenter notre monnaie. Qu'attendons nous de lui ?
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).
[...]
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).
Regardons déjà ce que Dring t'a répondu quand tu lui as proposé les décimaux à virgules fixes avec deux chiffres après la virgule :
Le truc chiant avec les devises, c'est qu'elles n'ont pas toutes 2 décimales. Du coup, est-ce que dans ce code la valeur du delta peut être une variable ? Je crains que non.
et maintenant regardons, par exemple, les règles fixées par la Communauté Européenne lors de l'introduction de l'euro dans la publication The introduction of the euro and the rounding of currency amounts. On y trouve dans la section 3.3 Use of the conversion rate (p. 8) :
The rates have been adopted with six significant figures, e.g. 1 EUR = 40.3399 BEF.
Wherever these conversion rates are used, they will have to be applied exactly, i.e. with six significant figures; no rounding or truncating of the conversion rates is allowed (Article 4(2)).
Parmi les taux de change fixés par la commission, on trouve :
1 euro = 40.3399 francs belges
1 euro = 1.95583 marks allemands
1 euro = 166.386 pesetas espagnoles
personnellement j'appelle cela des décimaux flottants avec 6 chiffres significatifs (et donc le type decimal32, qui a 7 chiffres significatifs, permet de gérer les taux de changes dont la norme est légalement fixée par l'Union Européenne).
Les mêmes règles existent de nos jours pour les conversions avec les monnaie hors zone euro. Celles fixant la gestion des arrondis, les problèmes de double-conversion pour revenir dans la monnaie d'origine y sont également définies.
J'espère que ce simple exemple répond à la demande qui conclut ton commentaire :
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.
Pour ta partie sur la forme, tu as mal compris ce que je voulais dire.
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".
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 :
et si il utilise une module Decimal avec une telle interface, il exige que l'opération suivante retourne 0.74 :
Decimal.(round2(dec"0.70"*dec"1.05"))
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, il veut une bibliothèque qui lui fournisse cela ou un type primitif du langage. Ici le type sera abstrait (en théorie des types on parle de type existentiel1) ce qui est la base d'un idiome standard en programmation : l'encapsulation. ;-) Et du point de vue de l'utilisateur, rien ne le distingue d'un type primitif : il ne peut rien faire d'autre que de l'utiliser à partir des fonctions exportées par le module.
C'est là toute la distinction entre la représentation abstraite du type de données, déterminée par sa spécification, et la représentation concrète effectivement utilisée par le module pour l'implantation. Je n'ai jamais dit qu'il fallait tout reconstruire à la main, mais seulement que le seul type des entiers naturels permet d'être utilisé pour faire cela, rien de propre au type des flottants binaires.
Je te disais en note de bas de page qu'il y a des articles sur le sujet : utiliser les flottants binaires comme représentation concrète pour implanter la norme IEEE-754 des flottants décimaux. En voici un : Implementing Decimal Floating-Point Arithmetic through Binary: some Suggestions, avec parmi les co-auteurs Jean-Michel Muller que tu as cité dans un de tes commentaires. En voici le résumé :
We propose algorithms and provide some related results that make it possible to implement decimal floating-point arithmetic on a processor that does not have decimal operators, using the available binary floating-point functions. In this preliminary study, we focus on round-to-nearest mode only. We show that several functions in decimal32 and decimal64 arithmetic can be implemented using binary64 and binary128 floating-point arithmetic, respectively. We discuss the decimal square root and some transcendental functions. We also consider radix conversion algorithms.
on les appelle ainsi car ils se définissent par un énoncé de la forme : « il existe un type t tel que ... » où la seule chose que l'on sache de lui se trouve dans les ..., c'est-à-dire dans les valeurs et fonctions exportées par le module mais qui cache sa représentation concrète à l'utilisateur afin de maintenir des invariants. ↩
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
[^] # Re: Il faut bien lire ce qu'on lit!
Posté par kantien . En réponse au journal Le retour de la vengeance de la virgule flottante. Évalué à 3. Dernière modification le 27 janvier 2018 à 15:48.
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).
Regardons déjà ce que Dring t'a répondu quand tu lui as proposé les décimaux à virgules fixes avec deux chiffres après la virgule :
et maintenant regardons, par exemple, les règles fixées par la Communauté Européenne lors de l'introduction de l'euro dans la publication The introduction of the euro and the rounding of currency amounts. On y trouve dans la section 3.3 Use of the conversion rate (p. 8) :
Parmi les taux de change fixés par la commission, on trouve :
personnellement j'appelle cela des décimaux flottants avec 6 chiffres significatifs (et donc le type decimal32, qui a 7 chiffres significatifs, permet de gérer les taux de changes dont la norme est légalement fixée par l'Union Européenne).
Les mêmes règles existent de nos jours pour les conversions avec les monnaie hors zone euro. Celles fixant la gestion des arrondis, les problèmes de double-conversion pour revenir dans la monnaie d'origine y sont également définies.
J'espère que ce simple exemple répond à la demande qui conclut ton commentaire :
Pour ta partie sur la forme, tu as mal compris ce que je voulais dire.
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 :
et si il utilise une module
Decimalavec une telle interface, il exige que l'opération suivante retourne0.74:Toi ce que tu dis, c'est que l'on peut prendre
t = floatet définirroundde 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, il veut une bibliothèque qui lui fournisse cela ou un type primitif du langage. Ici le type sera abstrait (en théorie des types on parle de type existentiel1 ) ce qui est la base d'un idiome standard en programmation : l'encapsulation. ;-) Et du point de vue de l'utilisateur, rien ne le distingue d'un type primitif : il ne peut rien faire d'autre que de l'utiliser à partir des fonctions exportées par le module.C'est là toute la distinction entre la représentation abstraite du type de données, déterminée par sa spécification, et la représentation concrète effectivement utilisée par le module pour l'implantation. Je n'ai jamais dit qu'il fallait tout reconstruire à la main, mais seulement que le seul type des entiers naturels permet d'être utilisé pour faire cela, rien de propre au type des flottants binaires.
Je te disais en note de bas de page qu'il y a des articles sur le sujet : utiliser les flottants binaires comme représentation concrète pour implanter la norme IEEE-754 des flottants décimaux. En voici un : Implementing Decimal Floating-Point Arithmetic through Binary: some Suggestions, avec parmi les co-auteurs Jean-Michel Muller que tu as cité dans un de tes commentaires. En voici le résumé :
on les appelle ainsi car ils se définissent par un énoncé de la forme : « il existe un type
ttel que ... » où la seule chose que l'on sache de lui se trouve dans les..., c'est-à-dire dans les valeurs et fonctions exportées par le module mais qui cache sa représentation concrète à l'utilisateur afin de maintenir des invariants. ↩Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.