snowball a écrit 168 commentaires

  • [^] # Re: Toi Tu vas avoir des problèmes avec le corps enseignant ;)

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

    Parfois je me dis que certains mériteraient d'avoir des problèmes avec leur corps en saignant.

  • [^] # Re: Ne règle pas le "problème" du journa précédent

    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 22 janvier 2018 à 14:53.

    D'après ce que j'ai lu, il donnera plutôt 2-0.8-1.2 = -5.551115123125783e-17 ± 3e-17
    (et même sûrement plus que 3e-17 vu que les trois nombres ont des exposants différents, il y a phénomène d'absorption)

  • # Pas si vite :)

    Posté par  (site web personnel) . En réponse au journal Le retour de la vengeance de la virgule flottante. Évalué à 10. Dernière modification le 22 janvier 2018 à 14:14.

    il est possible qu'à un horizon indéterminé mais réel, ce problème soit réglé ou sensiblement atténué et qu'on puisse travailler sur des nombres à virgule flottante sans erreur et sans perte majeure de performance.

    Malheureusement non.

    Ce système continue à calculer de façon approchée et ne résout pas le "problème" évoqué dans le journal précédent qui traitait de ce sujet.

    Par exemple, pour le calcul 2-1.8-0.2, chacun des réels 1.8 et 0.2 sera déjà arrondi dès qu'il sera stocké dans les registres du FPU. Ce qu'ajoute ce système c'est de conserver un majorant des erreurs qui seront (de toute façon) commises (pour l'entrée en mémoire, puis pour les deux opérations) ce qui permet à l'utilisateur d'avoir un encadrement du résultat exact géré par le FPU lui-même.

    A noter que le système en question ne s'embarrasse pas de la base 10 et continue à gérer des flottants en base 2 (pour lesquels 0.1 n'est pas représentable en machine).

    En fait, ce que je trouve "amusant" dans tous ces échanges, c'est qu'on démontre en faisant un tout petit peu de math, que le souhait d'exactitude est impossible à atteindre, mais que certains veulent continuer à y croire. Comme si la démonstration n'avait pas valeur de vérité. En gros, on revient inlassablement à des problèmes de compréhension des concepts en math.

  • [^] # Re: Que disent les programmes du primaire

    Posté par  (site web personnel) . En réponse au journal [Humour] vers un monde différent. Évalué à 2.

    Si tu veux que python ait le même comportement qu'une calculatrice, il suffit d'écrire une fonction ad hoc den utilisant un code de troncature du genre (pour des résultats sur douze chiffres):

    Python 3.6.4 (default, Dec 23 2017, 19:07:07) 
    [GCC 7.2.1 20171128] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> print ("%.12f" % (0.1+0.2))
    0.300000000000

    Python donnera ainsi des résultats arrondis du même type que la calculatrice (comme le font les tableurs et autres). Attention, on perdra du coup de la précision sur presque tous les calculs sauf, en apparence, pour ceux que tu juges "élémentaires".

  • [^] # Re: Que disent les programmes du primaire

    Posté par  (site web personnel) . En réponse au journal [Humour] vers un monde différent. Évalué à 3.

    «liée à une mauvaise conception de ce que sont les nombres.»
    … dans les machines.

    Non, je veux vraiment dire "dans les têtes de ceux qui pratiquent les maths !"*

    ", bien que la discussion porte initialement sur des 0.xxxx "finis","

    C'est bien ce que je disais: c'est un problème de compréhension des nombres.

    Car 0.2345 est une notation raccourcie pour écrire une… fraction décimale ! En l'occurrence 2345/10000. C'est donc une fraction toute bête (enfin, plus compliquée que 1/3 quand même).

    Dire que ce décimal, c'est à dire cette fraction, est finie n'a aucun sens. (j'ai bien vu que tu avais mis des guillemets mais malgré tout, on voit là la confusion qui règne). C'est le développement en base 10 qui est fini. Dans une autre base, le développement sera différent et ne sera plus forcément fini. Ce n'est pas une propriété intrinsèque du nombre mais une propriété liée au choix d'une base. Ce problème de conception est le fil conducteur du journal en fait.

    Pour l'étude des programmes d'enseignement, rien à redire, les classes primaires ont été évoqués bien en amont dans ce fil (probablement pour évoquer la simplicité intuitive des calculs demandés et non pas la réalité pédagogique de la chose).

    Évoquées peut être, mais pour dire des choses fausses très souvent. Dans la discussion, certains ont avancé que 0.1 + 0.2 était un calcul de CE2. Or ce n'est pas du tout comme ça dans la réalité. C'est un calcul de CM2 qu'on fait après avoir découvert les rationnels et ça change absolument tout. En effet, ceux qui ont appris les maths dans cet ordre seront très probablement surpris de l'importance que tu accordes aux fractions décimales et pas aux autres (comme si elles avaient un intérêt supérieur aux autres fractions et qu'il faille absolument, juste pour elles, des résultats exacts avec une machine !).

    Dans les petites classes, les professeurs qui utilisent la calculatrice, font d'abord des calculs avec les fractions et les élèves, dès leurs premiers calculs (genre 2/3) voient qu'une calculatrice fait des approximations pour écrire les résultats et ne donne que très rarement un résultat juste. Les élèves voient donc les erreurs de la calculatrice même pour leurs tout premiers calculs. Le résultat donné par Python n'aura donc rien de surprenant pour eux puisque c'est ce qui s'est passé dès le début de leur utilisation de la calculatrice.

    Comprends-tu que si tu "exiges" de l'exactitude sur les calculs avec les fractions décimales du type \frac{n}/{10^k} (les décimaux) alors que tu ne l'exiges pas sur des fractions plus "simples" du type 2/3, c'est uniquement parce que tu accordes une importance étrange aux décimaux (liée certainement à la façon dont on a présenté les nombres dans ton parcours scolaire). C'est pour ça que je parle de problème de conception des nombres pour ceux qui trouvent étrange ce qui se passe avec les floats. Ce sujet n'est pas vraiment un problème informatique, mais un problème lié à des conceptions mathématique biaisées par un apprentissage qui a focalisé inutilement sur les décimaux (en gros les générations qui ont fait un CM1 avant 2008).

  • # Que disent les programmes du primaire

    Posté par  (site web personnel) . En réponse au journal [Humour] vers un monde différent. Évalué à 4.

    Pour compléter un peu, je suis allé vérifier la progression pédagogique concernant les nombres.

    Donc, pas de décimaux ni de fractions avant le CM1.

    A partir du CM1, depuis 2008, la progression est la suivante:

    • D'abord les fractions
    • Ensuite les fractions dites décimales et leur écriture à l'aide de la notation décimale (virgule). Pour un enfant aujourd'hui 1.01 est une notation raccourcie pour écrire 1 + 1/100=101/100.

    http://circ-andelys.spip.ac-rouen.fr/spip.php?article258
    Bref, un élève de CM1 commence par faire des calculs du genre 2/3 pour lesquels sa calculatrice donne un résultat faux ! Jette t-il pour autant sa calculatrice ? Non, car on lui apprend que 2/3 ne peut pas se représenter correctement en machine. Ensuite, il fait des calculs avec des fractions décimales, et sa machine donne parfois un résultat exact mais le plus souvent un résultat faux (sauf dans quelques cas rares liés au quotidien).
    Quand il touchera à Python, il se dira, s'il a compris ce qu'on lui a dit, que tout comme sa machine se trompe pour 2/3, python se trompe pour 1/10 + 2 / 10, ce qui n'a absolument rien de surprenant.

    Il n'a donc aucune raison, vu la conception qu'on lui enseigne, de s'étonner que quand on manipule des fractions (décimales ou pas), la machine donne dès le tout début de son apprentissage des résultats faux. C'est pour ça que je dis qu'il s'agit ici d'une obsession du décimal liée à une mauvaise conception de ce que sont les nombres.

  • [^] # Re: Commentaire de soutien ;-)

    Posté par  (site web personnel) . En réponse au journal [Humour] vers un monde différent. Évalué à 3.

    Ce qui m'intéresse c'est la vérité mathématique et pas la vérité IEEE.

    Quand ta calculatrice affiche 2/3=0.6666666666667 la blâmes-tu ? Pourtant ce résultat est tout aussi faux (même davantage car plus imprécis) que quand python fait un calcul du genre 0.1+0.2=0.30000000000000004. C'est exactement le même problème. Ce qui se passe c'est que certains ont une tendance étrange à focaliser sur les décimaux et voudraient absolument qu'avec les décimaux une machine calcule exactement alors qu'ils acceptent que pour d'autres nombres ça ne calcule pas juste.

    Cette focalisation sur les décimaux est liée à une mauvaise compréhension de ce que sont les nombres et donc de l'impossibilité de les représenter correctement en machine pour l'immense majorité d'entre eux.

    J'ajoute que quand on fait un cours sur la représentation des nombres dans une machine, donc sur l'impossibilité de les représenter correctement (sur une machine quelconque, calculatrice ou autre), il n'y a aucune difficulté. Le tout est d'avoir reçu un cours convenable traitant de ce problème qui est, clairement, un problème de conceptualisation des nombres avant d'être un problème informatique.

    J'ajoute que dans les programmes du CE2 on ne commence plus par les décimaux mais par les rationnels depuis plus de 10 ans ce qui explique peut être pourquoi les jeunes élèves du secondaire n'ont pas ce problème de focaliser à ce point sur les décimaux.

    L'enseignement antérieur était de calculer d'abord avec les décimaux puis les fractions (en plus on utilisait la monnaie pour parler des décimaux et donc beaucoup d'élèves avaient des difficultés dès qu'il y avait plus que deux chiffres après la virgule). C'était une énorme bêtise sur le plan mathématique puisque les décimaux sont, par définition, des rationnels très particuliers et que toutes les règles de calcul permettant de les manipuler proviennent en fait de celles sur les fractions !

    Quant à la vérité mathématique (c'est à dire les calculs exacts j'imagine), c'est tout simplement une utopie sur une machine.

  • [^] # Re: Commentaire de soutien ;-)

    Posté par  (site web personnel) . En réponse au journal [Humour] vers un monde différent. Évalué à 2.

    Je vais pas faire long, mais juste pour dire qu'en diffusant cette info dans un contexte de labo, plutôt scientifique, développement logiciel (fiabilité et cie), j'ai les mêmes réactions.

    Alors ça, c'est franchement pas rassurant. Cela dit, ces problèmes sont assez rarement enseignés (et derrière il faut finalement avoir compris profondément le concept de nombre en math, ce qui est très, très peu fréquent)

  • [^] # Re: Commentaire de soutien ;-)

    Posté par  (site web personnel) . En réponse au journal [Humour] vers un monde différent. Évalué à 2.

    Donc, dans les bouquins de mathématiques, (une fraction x - une fraction x) = 0 , (un complexe x - un complexe x) = 0, et même (un ensemble x - un ensemble x) c'est l'ensemble vide (i.e. le "0" des ensembles).

    Chez les flottants aussi, x-x=0.

    c) oui également, Decimal est effectivement un moyen de cacher/surcharger/contourner ce qui "tracasse"

    Pas vraiment. Ça ne règle le problème Decimal (x) * Decimal (1/x) = Decimal (1) que quand x est de la forme 2*n * 5*m, c'est à dire quasiment jamais (même pas pour x=3 !!).

    Je le reformule également : en dehors d'un milieu geek "conditionné", le constat évoqué fait pour le moins sourire.

    Les floats que propose Python sont à destination du milieu geek "conditionné" (i.e qui comprend ce qu'est un float). Python n'est pas une calculatrice. Mais de toute façon, toute personne qui a déjà utilisé sa calculatrice est déjà habituée aux résultats approchés même pour des calculs évidents du genre 3 * 1/3 = 1 et ça ne fait pas sourire. Elle se rend juste compte qu'une machine qui ne gère que du fini, ne peut gérer exactement les nombres: elle ne peut faire, quasiment à chaque fois, que des approximations.

    une simple calculatrice scientifique qui couvre correctement son domaine de fonctionnement (exact pour les décimaux usuels, notation ingénieur/scientifique ailleurs)

    Non. Une calculatrice de base "se trompe" sur 1.000 000 1 * 0.999 999 9 qui sont deux décimaux très "raisonnables". Elle "se trompe" quasiment sur tous les calculs impliquant les décimaux (en fait la probabilité qu'une calculatrice donne un résultat juste dès qu'elle fait des multiplications ou divisions sur des décimaux aléatoires est de moins d'un milliardième (si on considère une machine sachant gérer 13 chiffres de mantisse).

    Cela est donc bien possible.

    En fait, bc fait

    01:53:35 ~: bc
    bc 1.07.1
    Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006, 2008, 2012-2017 Free Software Foundation, Inc.
    This is free software with ABSOLUTELY NO WARRANTY.
    For details type `warranty'.
    1.01*0.99
    .99

    C'est à dire un résultat faux. Alors oui, tu peux évidemment pousser la mantisse utilisée par bc un peu plus si tu es "conditionné" aux problèmes que pose le calcul numérique sur une machine, mais tu tomberas sur le même problème un tout petit peu plus loin.

    On peut, modulo des coûts de calcul très importants, colmater quelques erreurs (une sur un milliard environ) mais on ne peut pas régler le problème tout court. Il y aura toujours des calculs quasi évidents qui ne seront pas correctement effectués par une machine.

    Mais ça interpelle. C'est tout.

    Tout comme ça m'a interpellé quand j'ai vu que presque tous les calculs faits par une calculatrice sont faux (sauf pour quelques opérations sur certains décimaux qui donnent une illusion d'exactitude au néophyte)

    PS : Ah oui, en La(TeX) aussi c'est bon à première vue, 0.2+0.4 donne 0.60000 ;-)

    Il a tronqué un résultat faux au moment de l'affichage et qui du coup redonne une impression d'exactitude du calcul (il arrondit un arrondi faux qui redonne un résultat "exact" )

    PS2 : 4ème implémentation déjà évoquée, un tableur. Ça se comporte, suffisamment bien, que ce soit pour les décimaux que pour des valeurs grandes.

    Non. Ça fait les mêmes bêtises, puis ça les cache avec des algos qui tentent de prédire ce que veut probablement l'utilisateur (en fonction de la configuration de l'arrondi dans le format de cellule). Calc utilise des floats derrière ton dos, fait, comme toute machine, les mêmes approximations, puis formate l'affichage pour qu'avec certains décimaux tu aies l'illusion que son calcul est juste, ce qui, évidemment, n'est pas vrai dans presque tous les cas.

    En fait, il n'y a pas vraiment de problème:

    • Si tu veux une addition / soustraction exacte des "petits" décimaux, tu as des modules pour ça (par contre ils vont se vautrer quasiment sur chaque division, même élémentaire) et ça va coûter cher en perf.
    • Si tu as compris, que de toute façon, le calcul juste sur une machine n'arrive que dans quelques cas exceptionnels et qu'une précision aux alentours du 17ème chiffre après la virgule te suffit alors tu as les floats (avec beaucoup d'efficacité machine).
    • Dans 99% des cas d'utilisation, l'exactitude souhaitée sur quelques rares petits décimaux n'ayant aucun intérêt, et coûtant environ 50 fois plus de cycles d'horloge qu'un calcul avec des floats, on n'a que très rarement l'intérêt d'utiliser le module decimal.

    Bref, on a une solution informatique convenable à quasiment tous les problèmes numériques usuels en fonction de chaque besoin spécifique.

    Les sciences (mathématique/informatique) ont fait depuis longtemps le tour théorique de cette question en délimitant (démonstration à l'appui) précisément ce qu'on peut faire et ce que l'on ne peut pas faire, ce qu'il est intéressant de faire ou ce qu'il faut éviter de faire dans le domaine de la représentation des nombres en machine.

    Tout cela a déjà été dit, dans les posts au dessus, mais certaines incompréhensions ayant nécessité beaucoup d'explications ont fini par noyer les messages très clairs donnés par beaucoup d'intervenants.

    Les incompréhensions, quand on creuse un peu, viennent de représentations erronées de la nature même des nombres. Ce n'est pas étonnant car ces concepts sont en fait loin d'être évidents à comprendre surtout quand on croit (sincèrement) les maîtriser.

  • [^] # Re: Petit résumé et tests dans la réalité

    Posté par  (site web personnel) . En réponse au journal [Humour] vers un monde différent. Évalué à 1.

    Ah donc c'est encore pire, c'est carrément l'affectation entre deux décimaux ou l'appel à la lib C qui bouffe tout ce temps. Ca va être compliqué d'y changer quoi que ce soit. J'imagine en plus l'usine à gaz, s'il fallait contrôler les affectations pour voir si l'opérande peut représenter un décimal ou non, auquel il faudrait basculer dans un autre type, donc convertir (avec le coût de la conversion au passage).

  • [^] # Re: Petit résumé et tests dans la réalité

    Posté par  (site web personnel) . En réponse au journal [Humour] vers un monde différent. Évalué à 5.

    c'est possible, et ça prend pas x50 tellement Python il est mauvais niveau perfos

    Tu verras une différence de perfo de l'ordre de x50 lorsque ta boucle python devra faire, à chaque tour, disons une dizaine d'appels à la lib C decimal, c'est à dire quand le coût de la boucle python sera devenue négligeable. Le bench qui consistait à n'exécuter qu'un appel à une lib C ne permet pas de mesurer ce qu'on souhaite mais plutôt le coût de la boucle python.

    Il y a aura eu, de toutes façons, quoique tu fasses, une multiplication par 50 des cycles nécessaires en interne pour finalement calculer les mêmes approximations dans 99.9999999999% des cas (pour 1000 milliards d'opérations sur des mantisses de 13 chiffres, en moyenne environ une seule concerne une opération exacte sur deux décimaux). C'est un gâchis énergétique pour une simple focalisation excessive sur l'une des approximations que fait, de toutes façons, la machine dans 99.9999999999% des cas.

    Etant donné que ni decimal, ni float, ne règlent le problème élémentaire 3 * 1/3 = 1, ni 7 * 1/7 = 1 ni etc…, les informaticiens ont fait le choix de la base 2, qui a l'avantage d'être parfaitement adapté aux machines classiques, donc plus efficace et moins énergivore.

    Si un jour chez Python, ils se mettaient à faire ça par défaut, il y aurait un impact majeur pour toutes les applications utilisant fortement float (traitement d'image, vidéo etc) pour lesquelles il n'y aurait aucun bénéfice sinon une division de perfs par 50 pour les plus gourmandes en calcul et par 2 ou 3 les autres. Côté client c'est donc presqu'à chaque fois totalement nul: perte de temps, d'énergie, et aucun bénéfice concret sur sa vidéo ou son image.

    Le seul cas intéressant serait pour des applications financières qui font de la virgule fixe ou quand on se sert de python comme une calculatrice. Pour cela, le module decimal python a été développé, qui gère de la base 10, c'est coûteux évidemment, mais si on a ce besoin spécifique, ça existe, dans d'autres langages aussi d'ailleurs.

    Du coup, y a aucun problème, il est urgent de ne rien toucher !

    Ensuite il te reste à comprendre la différence fondamentale qui reste entre écrire "float f=0.1" en C et "f=0.1" en Python pour finir de comprendre ce que j'essaie de dire depuis 400 posts déjà…

    Oui, j'ai effectivement besoin de comprendre (enfin de moins en moins je crois).

  • [^] # Re: Petit résumé et tests dans la réalité

    Posté par  (site web personnel) . En réponse au journal [Humour] vers un monde différent. Évalué à 1.

    Et si tu lis cette conversation, tu verras que l'implementation Decimal (cdecimal) devient plus raisonnable pour un passage à default.

    Bof, on perd des dizaines de facteurs de performance (cf https://linuxfr.org/nodes/113338/comments/1725062 pour comparer un float*float et un decimal*decimal )
    Quand on noie le tout dans du python ça se voit un peu moins, mais c'est inutilement énergivore (souvent aux alentours de 50 fois plus de cycles) et ça n'a qu'un intérêt ultra limité vu que l'exactitude n'est effective que dans la proportion d'une opération sur 1000 milliards (pour une mantisse sur 13 chiffres).

    Les manipulations arithmétiques nécessaires pour traiter les décimaux sont beaucoup plus coûteuses en décimal qu'en binaire.
    Par exemple, les calculs nécessitent en permanence des multiplications et divisions par 10. En base 2, multiplier/diviser par 2 correspond à un seul shift (1 cycle d'horloge). Par contre, multiplier par 10 c'est le coût d'une vraie multiplication (6 cycles) et diviser par 10 coûte environ 12 cycles (grâce à la division magique par une constante connue du compilateur https://stackoverflow.com/questions/30790184/perform-integer-division-using-multiplication )

  • [^] # Re: Petit résumé et tests dans la réalité

    Posté par  (site web personnel) . En réponse au journal [Humour] vers un monde différent. Évalué à 0.

  • # Petit tests de la librairie C decimal (libmpdec)

    Posté par  (site web personnel) . En réponse au journal [Humour] vers un monde différent. Évalué à 10.

    Bonjour à tous et noyeux joel !

    Pour commencer un petit bench de la librairie et le comparatif avec des float (double)

    Un petit test que pourront apprécier ceux qui veulent connaître l'impact de l'utilisation des décimaux dans une machine classique.

    Il est réalisable par tout un chacun en se rendant sur le site officiel pour obtenir la dernière version à cette adresse http://www.bytereef.org/mpdecimal/quickstart.html

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <mpdecimal.h>
    
    int main()
    {
        mpd_context_t ctx;
        mpd_t *a, *mul;
        double fa=1.01, fmul=1.000001;
        clock_t start_clock, end_clock;
        unsigned long long turns = 100000000;
    
    
        mpd_init(&ctx, 16);
        ctx.traps = 0;
        a = mpd_new(&ctx);
        mul=mpd_new(&ctx);
        mpd_set_string(a, "1.01", &ctx);
        mpd_set_string(mul,"1.000001",&ctx);
        start_clock = clock();
        for (unsigned long long u=0; u < turns; u++)
        {
          mpd_mul (a,a,mul,&ctx);
        }
        end_clock = clock();
    
        printf("Decimal time: %f\n",
                   (double)(end_clock-start_clock)/(double)CLOCKS_PER_SEC);
        mpd_del(a);
    
        start_clock = clock();
        for (unsigned long long u=0; u < turns; u++)
        {
        fa*=fmul;
      }
        end_clock = clock();
        printf("Float time: %f\n %f\n",
                   (double)(end_clock-start_clock)/(double)(CLOCKS_PER_SEC),fa);  
        return 0;
    }

    Le résultat est que la boucle numéro 1, prend en moyenne 43 fois plus de temps que la seconde qui fait la même chose pour les mêmes valeurs d'opérandes.

    Vous trouverez sûrement, si vous testez, des ratios parfois inférieurs, parfois très supérieurs aussi (sur une autre machine c'est aux alentours de 70).

    Pour comparer ce qui est comparable, j'ai, conformément à la doc de la librairie, initialisé le contexte à MPD_DECIMAL64 qui correspond à une taille des opérandes de 64 bits comme celle des double sur ma machine (64 bits) qui concerne la deuxième boucle. J'ai compilé avec -O2 dans les options de GCC.

    Pourquoi utiliser un bench python faisant appel à une librairie C n'a aucun sens

    Parce que la boucle python coûte plus cher que ce qu'on souhaite mesurer (environ 30 fois plus)!
    Par contre, si on reste cohérent dans le bench, et qu'on fait du "full python" on retrouve le même ratio (obtenu avec la lib libmpdec) comme l'expérience a déjà été faite dans des posts au dessus.

    Etait-ce prévisible ?

    Bien évidemment, on se doute, que lorsque l'on remplace une seule instruction assembleur d'addition sur des flottants (qui prend maximum 2 cycles d'horloge FPU), par l'arsenal de cette lib, il devient évident, que la librairie décimale ne peut pas ne prendre que 4 cycles (rien que l'appel à mpd_add et les empilements que ça génère, coûte au moins 10 cycles)

    Pourquoi on trouve des benchs qui semblent contradictoires sur le site de la lib

    D'abord parce que dans les benchs proposés, les calculs sont noyés dans plein d'autres (exemple, le calcul du mandebrot et son algo d'échappement).
    Et peut être aussi, parce que sinon c'est moins attractif (pour être taquin).

    Conclusion

    Je ne cherche à ridiculiser personne ici, je ne suis pas dans la guéguerre, j'interviens sur un sujet que je pense connaître assez, vu que c'est ma formation et accessoirement mon métier. Quand je dis que quelqu'un a des problèmes math, ça peut être tout simplement vrai et çe n'est pas pour autant que je méprise mon interlocuteur. A l'avenir, par contre, ça serait sympa de pas se faire traiter de con ou de guignol ou que sais-je encore, pour des raisons qui tiennent d'avantage de la lutte d'égo que de la recherche de ce qui est vrai ou faux.

    Voilà, bonnes fêtes à tous, bons benchs pour les plus malades d'entre vous (!), et mangez pas trop d'huîtres mélangées au foie gras et au chocolat, c'est moyennement digeste :)

  • [^] # Re: Petit résumé et tests dans la réalité

    Posté par  (site web personnel) . En réponse au journal [Humour] vers un monde différent. Évalué à 1.

    tu te sers de l'implémentation informatisé actuelle pour valider tes maths.

    Non car ce ne sont pas mes maths mais les maths. Elles n'ont pas à être validées car on sait prouver qu'elles sont vraies (c'est dingue ça hein ?). Les implémentations qu'on fait de tout ça en info, même si elles sont optimales ces implémentations, auront des coûts incompressibles (ça se démontre aussi. Incroyable les maths en fait !). Et au minimum du minimum tu pourras pas descendra en dessous d'un ratio d'environ 50 (sauf à changer de paradigme en changeant totalement de type de machine -genre quantique puisque tu aimes-).

    Ces certitudes sont l'apport des mathématiques que connaissent très bien les ingés d'IBM et tous ces singes savants qui ont compris les concepts dont on parle :) Ton problème c'est que tu les ignores, que visiblement ça te frustre au point d'insulter, d'agresser les autres, et visiblement, ça augmente une aigreur que je sens habituelle chez toi. Je me trompe ?

    Bonne journée à toi,
    je te la souhaite la plus agréable qui soit.
    Peace.

  • [^] # Re: Pas la musique…

    Posté par  (site web personnel) . En réponse au journal [Humour] vers un monde différent. Évalué à 3.

    Bah il s'énerve et il insulte parce qu'il se rend compte, à ses dépends, qu'en math, on peut pas tricher pour masquer son ignorance :)
    Il a l'air aussi un peu aigri et mal dans sa peau (comme en témoignent ses préjugés sur les profs et les étudiants qui sortent d'école d'ingénieur).

  • [^] # Re: Petit résumé et tests dans la réalité

    Posté par  (site web personnel) . En réponse au journal [Humour] vers un monde différent. Évalué à 2.

    Quelle grosse connerie ? Tu peux expliquer un peu ?

  • [^] # Re: Petit résumé et tests dans la réalité

    Posté par  (site web personnel) . En réponse au journal [Humour] vers un monde différent. Évalué à 1.

    En attendant que le prof m'explique comment il fait un addition ou une multiplication sur un float… Et en une seule opération

    Tu sais ce que c'est un pipeline ?
    C'est ça https://fr.wikipedia.org/wiki/Pipeline_(architecture_des_processeurs)
    Il y a plusieurs instructions traitées séparément dans le même cycle d'horloge. C'est comme ça que la FPU arrive à traiter sa mantisse, son exposant, son bit de signe, et les éventuelles exceptions levées par NaN en seulement deux cycles de la FPU.

    (Au passage je vais me répéter: un calcul sur décimal est équivalent à un calcul d'entier avec un poil de glue.

    C'est là qu'il te manque des maths !

    Car si tu dois additionner, tu vas devoir réimplémenter ce que fait IEEE754, mais, là, tu n'as pas de pipeline et en plus tu fais tout en base 10 (donc les multiplications ne sont pas juste des shifts right ou left mais coûtent très cher (6 cycles minimum donc 6 fois plus qu'un décalage) et tu dois vérifier que ça déborde pas, donc faire des soustractions et regarder le bit de signe du résultat etc.

    Du coup ça donne le code du module decimal que j'ai collé concernant l'addition. On comprend alors que ta glue, elle coûte au moins largement 100 cycles (et encore ça c'est si fait de façon optimale). Ce n'est pas un problème d'implémentation car il y a des coûts incompressibles.

    Et de toute façon, au final, tu auras le même problème qu'avec les binaires mais en base 10 comme je l'ai montré avec le code utilisant decimal concernant la division par 3. Il se plante tout autant que les floats. Tu peux le tester toi même.

    Tu peux aussi tester ça

    from decimal import Decimal
    a=decimal('0.000375')
    s=decimal('0')
    for i in range (1000000):
      s += a

    et comparer avec

    from decimal import Decimal
    a=0.000375
    s=0
    for i in range (1000000):
      s += a

    Tu obtiendras

    14:05:05 ~/Téléchargements: time python bench_dec.py 
    real    0m10,239s
    user    0m11,388s
    sys 0m0,006s
    14:05:45 ~/Téléchargements: time python bench_float.py 
    real    0m0,142s
    user    0m0,161s
    sys 0m0,007s

    Soit une division des perfs par plus de 70. Mais bon, encore une fois, c'était totalement prévisible par …. les maths :)

    Voilà monsieur. Avec tout mon respect.

  • [^] # Re: Petit résumé et tests dans la réalité

    Posté par  (site web personnel) . En réponse au journal [Humour] vers un monde différent. Évalué à 2. Dernière modification le 23 décembre 2017 à 13:59.

    [le bouffon blabla…] qui se viande lamentablement sur le premier code qu'il écrit

    Tu peux expliquer ce que montre mon bout de code juste pour voir ?

    Si c'est le test avec m, (d'après ce que j'ai compris ça serait une erreur selon toi :) ;) ;) ), as tu compris que dans ce code on se fiche totalement de passer par m, d'avoir égalité, c'est juste un temps d'arrêt, c'est tout ! Personne n'a demandé à ce que cette valeur soit atteinte par le compteur ou quoi que ce soit du genre.

    Si ce test t'embête, tu peux remplacer ça par une boucle déterministe du genre

    for n in range (27000):
        a+=0.000375

    Ca ne changera rien et ça montrera de la même manière une division des perfs par 50 (car oui, c'est ce que montre ce bout de code). On n'avait d'ailleurs pas besoin de ce bench puisque j'avais, sans bench, expliqué ce ration d'environ 50, ici même, il y a deux jours, avec des maths de singe savant :) Incroyable non ?

  • [^] # Re: Petit résumé et tests dans la réalité

    Posté par  (site web personnel) . En réponse au journal [Humour] vers un monde différent. Évalué à 2. Dernière modification le 23 décembre 2017 à 13:42.

    As tu compris à quoi servait ce bout de code au moins ? As tu donc compris qu'il n'y a aucune erreur ?
    Indication: pour répondre à la deuxième question, il faut avoir répondu à la première correctement :)

    Quant à mes étudiants, j'ai beaucoup de chance, ce sont des singes savants mais, contrairement à d'autres, ils ont un niveau suffisant pour comprendre ces sujets.

  • [^] # Re: Petit résumé et tests dans la réalité

    Posté par  (site web personnel) . En réponse au journal [Humour] vers un monde différent. Évalué à 3.

    N'importe quel analyste aurait crié à l'infamie, aurait eu direct une attaque, face au benchark présenté par gUI parce que c'est typiquement le truc qu'on ne fait jamais CAR LES FLOTTANTS SONT INCAPABLES DE GARANTIR LA FIABILITÉ D'UNE TELLE ITÉRATION.

    Sans blague ! Ca fait 300 posts qu'on explique que ni float ni decimal ne le permettent.
    La preuve avec decimal (pas la peine de faire beaucoup d'itérations hein)

    from decimal import *
    i = Decimal('3')*(Decimal('1')/Decimal('3')) - Decimal('1') # Donc i=0
    for n in range (28):
            i*=10
    print(i) # devrait afficher 0

    Les ingénieurs de chez IBM, qui sont autant des singes savants que moi, ne prétendent ni mieux, ni le contraire. D'ailleurs à l'école ils ont appris, à cause de prof débiles comme moi, des maths, les corps, les anneaux, précision relative/absolue, dynamique, virgule fixe, algos d'approximations des fonctions usuelles etc. Les pauvres, toutes ces connaissances, pour apprendre à réfléchir, ça pas dû être facile tous les jours pour eux.

    Quant au ton que tu emploies, il est à la hauteur du "contenu".

  • [^] # Re: Petit résumé et tests dans la réalité

    Posté par  (site web personnel) . En réponse au journal [Humour] vers un monde différent. Évalué à 2.

    from decimal import *
    i = Decimal('3')*(Decimal('1')/Decimal('3')) - Decimal('1') # Donc i=0 pour tout enfant de CM1
    for n in range (28):
            i*=10
    print(i) # devrait afficher 0 pour tout enfant de CM1
    12:34:43 ~/Téléchargements: python aussi_absurde.py 
    -1

    Si tu voulais démontrer que float et decimal ne peuvent pas compter de façon exacte et fournissent rapidement des aberrations quelque soit l'implémentation retenue, bravo, ça fait 300 posts qu'on explique pourquoi. Et en plus tu sais quoi, on le prouve, on l'anticipe, on a largement dépassé ce stade de la compréhension avant même d'avoir construit les premiers processeurs.

  • [^] # Re: Petit résumé et tests dans la réalité

    Posté par  (site web personnel) . En réponse au journal [Humour] vers un monde différent. Évalué à 2.

    Cela dit, j'accepte sans problème ton mea culpa et je ne t'en tiens pas du tout rigueur. Au plaisir de te lire et encore une fois, peace !!!!

  • [^] # Re: Petit résumé et tests dans la réalité

    Posté par  (site web personnel) . En réponse au journal [Humour] vers un monde différent. Évalué à 2.

    Ce que tu ne comprends pas de ton côté, c'est les maths. Je te promets que c'est vraiment le problème de fond. Tu fais un blocage.

    Donc tu ne comprends pas les réponses, tu les crois à côté de la plaque. Par exemple, que racine de 2 ne soit pas représentable en machine je n'ai pas besoin de le dire puisque j'ai énoncé plus fort en rappelant que mêmes les rationnels ne le sont pas à cause de limites de la machine qui viennent beaucoup plus vite que tu ne le croîs).

    Dès le début tu crois que c'est le nombre de chiffres après la virgule affiché dans un résultat qui indique la précision des calculs faits. Dès le début je vois que tu n'as pas le niveau suffisant pour aborder le sujet. Au bout de 100 posts tu en étais encore à croire que python se trompait dès la première décimale (je cite !), ce qui montre clairement tes limites. Ou bien tu dis que le dernier chiffre affiché par une machine pour 2/3 ne devrait pas être un 7. Ces petits trucs qui ont l'air secondaire pour toi montrent qu'évidemment tu ne comprends pas bien le sujet dont tu parles dès que tu t'adresses à quelqu'un qui bosse sur ça la moitié de l'année.

    Comme tu n'as pas le vocabulaire sur les structures algébriques, tu ne comprends pas les problèmes de stabilité non plus.

    Tu ne comprends pas non plus les problèmes de dynamique que résolvent les floats et sur lesquels se vautre ton type Decimal en écrivant 10 fois qu'ils ne servent qu'aux perfs. Tu n'as pas non plus imprimé sur le gouffre en terme de mémoire qu'impliquerait ce genre de représentation alors que je t'ai expliqué par un calcul simple les 37,5% de perte.

    Tu racontes d'énormes salades en disant que chez Python ça réfléchit à passer à du decimal par défaut alors qu'en fait dans ton lien, Guido explique pourquoi il ne faut surtout pas faire ça (la question n'a duré que deux jours). Il dit la même chose que tous les intervenants ici: il dit des évidences en fait.

    Tu ne réfléchis pas techniquement au coût des opérations parce qu'il te manque les maths derrière donc tu crois même qu'additionner des decimaux peut prendre le même temps à 10% près qu'additionner des floats (tiens multiplie les pour voir).

    Désolé si c'est dur à entendre pour toi, mais c'est comme ça: si tu n'as pas un niveau suffisant en math pour argumenter sur ce sujet qui t'intéresse, je n'y suis pour rien.
    Par contre, ce sujet est intéressant, et nécessite pas mal de concepts de maths dont j'ai déjà fait la liste. Les apprendre c'est très satisfaisant pour l'esprit. Il n'y a pas d'âge pour se réconcilier avec les mathématiques.

  • [^] # Re: Petit résumé et tests dans la réalité

    Posté par  (site web personnel) . En réponse au journal [Humour] vers un monde différent. Évalué à 2.

    Voilà le code issu du module decimal servant à additionner deux décimaux.
    J'ai commenté les différentes parties en surbrillance. Je précise que c'est en python3.

        def __add__(self, other, context=None):
            """Returns self + other.
    
            -INF + INF (or the reverse) cause InvalidOperation errors.
            """
            other = _convert_other(other)
            if other is NotImplemented:
                return other
    
            if context is None:
                context = getcontext()
    
            if self._is_special or other._is_special:
                ans = self._check_nans(other, context)
                if ans:
                    return ans
    
                if self._isinfinity():
                    # If both INF, same sign => same as both, opposite => error.
                    if self._sign != other._sign and other._isinfinity():
                        return context._raise_error(InvalidOperation, '-INF + INF')
                    return Decimal(self)
                if other._isinfinity():
                    return Decimal(other)  # Can't both be infinity here
    
            exp = min(self._exp, other._exp)
            negativezero = 0
            if context.rounding == ROUND_FLOOR and self._sign != other._sign:
                # If the answer is 0, the sign should be negative, in this case.
                negativezero = 1    def __add__(self, other, context=None):
            """Returns self + other.
    
            -INF + INF (or the reverse) cause InvalidOperation errors.
            """
            other = _convert_other(other)
            if other is NotImplemented:
                return other
    
            if context is None:
                context = getcontext()
    
            if self._is_special or other._is_special:
                ans = self._check_nans(other, context)
                if ans:
                    return ans
    
                if self._isinfinity():
                    # If both INF, same sign => same as both, opposite => error.
                    if self._sign != other._sign and other._isinfinity():
                        return context._raise_error(InvalidOperation, '-INF + INF')
                    return Decimal(self)
                if other._isinfinity():
                    return Decimal(other)  # Can't both be infinity here
    
            exp = min(self._exp, other._exp)
            negativezero = 0
            if context.rounding == ROUND_FLOOR and self._sign != other._sign:
                # If the answer is 0, the sign should be negative, in this case.
                negativezero = 1
    
            if not self and not other:
                sign = min(self._sign, other._sign)
                if negativezero:
                    sign = 1
                ans = _dec_from_triple(sign, '0', exp)
                ans = ans._fix(context)
                return ans
            if not self:
                exp = max(exp, other._exp - context.prec-1)
                ans = other._rescale(exp, context.rounding)
                ans = ans._fix(context)
                return ans
            if not other:
                exp = max(exp, self._exp - context.prec-1)
                ans = self._rescale(exp, context.rounding)
                ans = ans._fix(context)
                return ans
    
            op1 = _WorkRep(self)
            op2 = _WorkRep(other)
            op1, op2 = _normalize(op1, op2, context.prec)
    
            result = _WorkRep()
            if op1.sign != op2.sign:
                # Equal and opposite
                if op1.int == op2.int:
                    ans = _dec_from_triple(negativezero, '0', exp)
                    ans = ans._fix(context)
                    return ans
                if op1.int < op2.int:
                    op1, op2 = op2, op1
                    # OK, now abs(op1) > abs(op2)
                if op1.sign == 1:
                    result.sign = 1
                    op1.sign, op2.sign = op2.sign, op1.sign
                else:
                    result.sign = 0
                    # So we know the sign, and op1 > 0.
            elif op1.sign == 1:
                result.sign = 1
                op1.sign, op2.sign = (0, 0)
            else:
                result.sign = 0
            # Now, op1 > abs(op2) > 0
    
    // 'A ce stade, on n a toujours pas commencé à additionner. Combien ont coûté toutes ces opérations ????'
    
            if op2.sign == 0:
    #' Ca y est, ils se mettent à additionner les numérateurs !!'
                result.int = op1.int + op2.int 
            else:
                result.int = op1.int - op2.int // ou les soustraire suivant les signes
    
    // 'Et c est reparti pour renormaliser le tout !!!'
    
            result.exp = op1.exp
            ans = Decimal(result)
            ans = ans._fix(context)
            return ans
    
            if not self and not other:
                sign = min(self._sign, other._sign)
                if negativezero:
                    sign = 1
                ans = _dec_from_triple(sign, '0', exp)
                ans = ans._fix(context)
                return ans
            if not self:
                exp = max(exp, other._exp - context.prec-1)
                ans = other._rescale(exp, context.rounding)
                ans = ans._fix(context)
                return ans
            if not other:
                exp = max(exp, self._exp - context.prec-1)
                ans = self._rescale(exp, context.rounding)
                ans = ans._fix(context)
                return ans
    
            op1 = _WorkRep(self)
            op2 = _WorkRep(other)
            op1, op2 = _normalize(op1, op2, context.prec)
    
            result = _WorkRep()
            if op1.sign != op2.sign:
                # Equal and opposite
                if op1.int == op2.int:
                    ans = _dec_from_triple(negativezero, '0', exp)
                    ans = ans._fix(context)
                    return ans
                if op1.int < op2.int:
                    op1, op2 = op2, op1
                    # OK, now abs(op1) > abs(op2)
                if op1.sign == 1:
                    result.sign = 1
                    op1.sign, op2.sign = op2.sign, op1.sign
                else:
                    result.sign = 0
                    # So we know the sign, and op1 > 0.
            elif op1.sign == 1:
                result.sign = 1
                op1.sign, op2.sign = (0, 0)
            else:
                result.sign = 0
            # Now, op1 > abs(op2) > 0
    
            if op2.sign == 0:
                result.int = op1.int + op2.int
            else:
                result.int = op1.int - op2.int
    
            result.exp = op1.exp
            ans = Decimal(result)
            ans = ans._fix(context)
            return ans

    En version float: c'est une seule ligne de code directement envoyée à la FPU et qui prend deux cycles d'horloge (impossible de faire moins).
    Rien que les 10 premières lignes de test de ce module prennent 10 fois plus d'opérations élémentaires.
    Donc si ton module decimal prend le même temps qu'avec les floats c'est que ton module est bogué et qu'il est resté en float tout le temps.