Tu devrais ouvrir une entrée dans le suivi, ça ressemble à un problème d'interprétation du CSS (il y a des erreurs dans la mise en page et l'insertion des images correspondant aux formules LaTeX dans le texte).
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
Ce qui me désole, c'est de tout ramener à des notions de mathématiques, en faisant abstraction du besoin de millions de codeurs.
Pas le temps de développer, mais on est bien obligé de tout ramener à des notions mathématiques : l'informatique ce n'est que des maths dans le fond. Cela étant, on ne fait pas abstraction du besoin de millions de codeurs : il existe des bibliothèques de calcul à virgule fixe ou virgule flottante en base 10 pour la plupart des langages. On dit juste que si tel est son besoin alors il faut les utiliser et non passer par des flottants en base 2.
J'en ai marre de corriger toujours les mêmes bugs après toutes ces années, du code qui génère une facture dont le total n'est pas égal à la somme des lignes qui la compose, et provoque la consternation de nos clients, et crée des problèmes de réconciliation qui font perdre du temps, et créent parfois des paniques (rigolez, mais quand deux lignes de plusieurs centaines de millions d'euros ne correspondent pas exactement, et qu'en plus il n'y a pas de seuil de tolérance, y'a de la sueur sur les claviers avant de comprendre d'où ça vient).
Si le programmeur n'a pas utilisé les bons outils pour la tâche qui lui est assignée, c'est une faute professionnelle : il mérite une bonne volée de bois de vert de la part de ses supérieurs hiérarchiques (vu les conséquences de son erreur).
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
Pourquoi écris-tu un "réelle" plutôt qu'un "réel" ?
Erreur de frappe, j'ai pensé réel et mes doigts ont écrit réelle. Mes doigts ils sont libres, un peu comme les pinceaux : l'autre jour je voulais peindre des enfants nus qui couraient dans un champ, à la fin je regarde la toile, et j'avais peint un pingouin ! :-P
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
La technique employée ressemble à l'arithmétique d'intervalles
C'est bien ce qu'il me semblait. Et en plus il y a un troll caché sur les brevets d'algorithmes (que ce soit logiciel ou matériel, accepter un brevet sur des algorithmes faut vraiment pas être centré :-/).
Sinon, depuis l'autre journal je suis tombé sur une approche des plus intéressantes : la représentation par fractions continues. :-) Elle est décrite dans ce rapport de recherche INRIA : Arithmétique Réelle Exacte par Fractions Continues de Jean Vuillemin (il date tout de même de 1987 ;-). L'idée étant de représenter une fraction continue, possiblement infinie, de manière finie via une continuation : vive la programmation fonctionnelle ! :-)
L'article décrit la théorie : le corps des fractions continues et deux algorithmes pour les fonctions algébriques (fractions de polynômes) et les fonctions transcendantes (exponentielle, logarithme, fonctions trigonométriques et hyperboliques) basées sur des formules de Gauss, Legendre et Lambert. C'est une approche géométrique (un réelle comme produit d'homographies) particulièrement élégante, dont voici le résumé :
Nous étudions une représentation des réelles calculables par fractions continues, qui prend en compte l'infini ∞ = 1 / O et l'indéfini ⊥ = 0 / 0. Deux algorithmes généraux sont introduits pour effectuer les opérations. L'Algorithme Algébrique, qui se particularise aux sommes et produits de fractions continues, opère de façon positionnelle, en produisant un terme du résultat par termes des paramètres. L'Algorithme transcendant, fondé sur la fraction continue de Gauss, permet le calcul d'une vaste classe de fonctions spéciales (exp, log …). Ces algorithmes ont été implantés en LeLisp, avec des performances très satisfaisantes.
« God gave us the integers. All the rest is man's work. » Leopold Kronecker
À l'époque Vuillemin en avait fait une implantation en LeLisp, mais il en existe une en Haskell présentée dans cette vidéo. Tu peux commencer par la vidéo, qui présente d'abord une autre bibliothèque Haskell basée sur une approche par intervalle en base 2 à la Cauchy1, puis décrit plus en détail l'approche par fractions continues.
Le code Haskell est assez court (cf le lien au-dessus). Il utilise des listes plutôt que des continuations car il tire partie de l'évaluation paresseuse de Haskell. Mais avec la bibliothèque Sequence de c-cube (qui a une approche par continuation) qui vient de sortir en version 1.0 combinée avec la bibliothèque Zarith, on doit pouvoir faire cela facilement en OCaml.
j'ai d'ailleurs été étonné que l'orateur ait du expliquer à son auditoire ce qu'était une suite de Cauchy. :-o ↩
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
143 ~ 2^7, 1977 ~ 2^11 et 304 ~ 2^8, d'où un couple adjectif+nom donne une entropie de l'ordre de 15 (=7 + 8) bits, deux tels couples donnent une entropie de 30, plus les 11 pour le verbe, on arrive aux alentours de 40 (du même ordre que dans le xkcd : 4 parmi 2^11 possibilités soit 4 * 11 = 44 bits d'entropie).
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
Ce qui m'intéresse c'est la vérité mathématique et pas la vérité IEEE.
La norme IEEE-754 respecte très bien la vérité mathématique, mais j'y reviendrais après.
Pour contextualiser un peu, j'en suis venu récemment à python (puis ce "problème") parce que Python va être enseigné de plus en plus en lycée. Bon, bah c'est simple : "Madame/Monsieur, votre truc marche pas, il ne sait pas calculer (calculs habituels décimaux) aussi bien que ma calculatrice"
Bien au contraire ! C'est un très bon prétexte pour leur faire travailler leurs mathématiques. :-)
Je m'explique en illustrant par une approche possible (je ne suis pas là pour produire du matériel d'enseignement) en partant de ce que les élèves maîtrisent bien : la base 10 (et c'est cela qui choque dans l'exemple du journal).
Là je ne fais que charger de quoi travailler avec des nombres flottants en base 10 : des décimaux, en somme; et je fixe une précision assez basse pour avoir de petits nombres.
Hop, on définit les nombres 1, 2, 3 et on fait quelques calculs avec. On voit un peu à quoi correspondait le ctx.prec = 3 de tout à l'heure (pour l'instant, c'est le chiffre de nombre après la virgule). Le résultat de la première opération doit être familière à tout lycéen : il sait que si l'on divise 1 par 3, il aura une infinité de 3 après la virgule et là il n'en garde que trois.
Pour la seconde opération, il sait très bien que 2 * 333 = 666 d'où 2 * 0.333 = 0.666. La fraction a était approximée avant la multiplication, mais ensuite le calcul de celle-ci est on ne peut plus conforme à la « vérité mathématique » (qui te tient tant à cœur). En revanche si l'on pratique directement la division de 2 par 3, puis que l'on approxime au plus proche en ne conservant que trois chiffres après la virgule, on obtient un autre résultat, à savoir 0.667.
On peut continuer et montrer quelques « étrangetés » (qui n'en seront sans doute pas pour des lycéens) du calcul selon les règles strictes de l'arithmétique mais avec des arrondis.
Et là c'est tout à fait compréhensible. Selon les règles strictes de l'arithmétique, on a bien 333 + 333 + 333 = 3 * 333 = 999. Et pour le dernier, on a bien 333 + 667 = 1000 ou dans notre cas 0.333 + 0.667 = 1.000, mais comme la précision est de 3 il n'affiche que 1.00. En fait la précision c'est la taille de la mantisse, c'est à dire que le nombre est vu comme , là où un /trois est vu comme .
Il me semble bien que tout ce qui précède est largement accessible à des lycéens. Il suffit ensuite de développer la chose en leur expliquant que le même genre de phénomène se produit si l'on prend une base 2 au lieu d'une base 10, et que c'est dans cette base que travaille python par défaut.
Les deux « erreurs » de calcul relèvent des mêmes principes mathématiques mais dans deux bases distinctes.
Pour revenir, et conclure, sur cette histoire de standard IEEE. Le calcul flottant en base 2 a été normalisé en 1985 sous le nom de standard IEEE-7554. En 2008, y a été ajouté une normalisation de la base 10 (utilisée ici par Python), et j'avais donné plus haut le lien vers la page de l'ingénieur IBM qui s'en est occupé. Python datant de 1990, les matériels ayant implanté le standard de 1985 dans leur FPU, on peut comprendre pourquoi, par défaut, ce langage utilise la base 2 et non la base 10.
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
Je comprends que l'ambiance se dégrade très vite ici.
Il n'y avait aucune agressivité dans mon commentaire, je ne faisais que résumer ce qui a été dit mainte et mainte fois au cours du fil.
contexte mathématique numérique théorique et donc justement pas en implémentations informatiques "biaisées"
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).
Oui, et cela est vrai même en arithmétique flottante quelque soit la base x - x vaut toujours 0, même en informatique « biaisée ».
oui également, Decimal est effectivement un moyen de cacher/surcharger/contourner ce qui "tracasse"
Non, c'est juste le moyen d'avoir accès à de l'arithmétique flottante en base 10, qui est celle que l'on a apprise au primaire. Par défaut les littéraux flottants sont calculés en base 2 en Python (comme dans de nombreux langage). Tu peux toujours utiliser Haskell si tu veux du polymorphisme ad-hoc sur les littéraux flottants.
le langage de Google, Go qui semble se comporter comme souhaité. (confirmation/infirmation ?)
corollaire : dans quel contexte mathématique numérique théorique, x - x n'est pas zéro… ?
Dans aucun, même dans l'arithmétique flottante en base 2 (en excluant les infinis, bien sûr ;-).
>>>0.2-0.20.0
Le principe de l'arithmétique flottante est de traiter des nombres de la forme :
Ce qu'il y a c'est que par défaut, python utilise la base 2 pour traiter les nombres à virgules, conformément à la norme IEEE-754, et que certains nombres décimaux ne sont pas représentables de manière finie dans une telle base (comme 0.2). Néanmoins cette norme a été révisée en 2008 pour y inclure également l'arithmétique flottante en base 10 (ce qu'implémente le module decimal de python) mais elle ne bénéficie pas d'accélération matériel (sauf chez des processeurs utilisés en autres dans la finance : SPARC64, POWER PC (Power 6), IBM System Z9).
En gros on nous explique que pour avoir les performances d'un avion de chasse, on ne pourrait plus voler comme un avion de lignes intérieures…
Non, on te dit d'utiliser le module decimal, il est fait pour cela. ;-)
Cela étant, en base 10 tu auras des problèmes similaires de nombres non représentables, et même en base 2 il faut juste savoir écrire ses opérations :
>>>2.0-(1.8+0.2)0.0
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
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.
Rien n'est moins sûr. Le modèle d'exécution de python est bien différent de celui du C.
cat << EOF > /tmp/test_dec.py> from decimal import Decimal as D> a, mul = D('1.01'), D('1.000001')> for i in range(0, 100):> EOF
cat << EOF > /tmp/test_float.py>a, mul = 1.01, 1.000001>for i in range(0, 100):>EOFfor i in `seq 10000`
> doecho" a *= mul" >> /tmp/test_dec.py
> echo" a *= mul" >> /tmp/test_float.py
> done
Là, je fais 100 boucles avec 10_000 multiplication par boucles.
time python3 -c "for i in range(0, 100): pass";time python3 /tmp/test_dec.py ;time python3 /tmp/test_float.py
real 0m0,026s
user 0m0,016s
sys 0m0,012s
real 0m0,344s
user 0m0,268s
sys 0m0,032s
real 0m0,178s
user 0m0,172s
sys 0m0,004s
Le temps de la boucle est négligeable et le facteur est toujours de 2.
Arthur n'a pas tort, le ton est monté inutilement et je te trouve bien agressif également dans ta manière d'intervenir (depuis un moment déjà dans ce journal).
Je pense n'avoir rien à apprendre en mathématique de ta part (peut être en analyse numérique, mais c'est vraiment un domaine qui ne m'a jamais passionné, je trouve cela ennuyeux à mourir), et déjà sur le journal de Blackknight sur le décalage de 64 bits, tu avais tendance à monter sur tes grands chevaux. J'avais tenter, sans succès, de désamorcer la chose par l'humour avec Homer et sa théorie de l'univers en forme de beignet, pour la simple raison que quand je multiplie deux cercles j'obtiens un beignet (la géométrie algébrique, c'est bon mangez-en :-). Et c'est cette structure géométrique (le beignet) qui m'avais permis d'identifier les points pathologiques dans la plupart des langages qui ont fait ce choix (plutôt que le cylindre, produit d'un cercle par un segment, comme Ada) pour des raison de performances sur les X86 (ça évite des tests dynamiques à l'exécution). ;-)
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
Il doit y avoir une erreur dans ton installation de python. Là tu nous sors l'implémentation en pure python, là où normalement tu devrais avoir une implémentation en C du module. Que te réponds cette commande :
>>>decimal.__libmpdec_version__'2.4.2'
Ça reste moins performant que des float (ce qui était prévisible) mais pas dans de telle proportion. Pour un comparatif avec des benchs plus précis, voir le site de libmpdec (c'est plutôt du simple au double pour les opérations de bases : addition, multiplication, division).
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
$ time ./bench_dec.py
real 0m0,106s
user 0m0,100s
sys 0m0,004s
$ time ./bench_float.py
real 0m0,076s
user 0m0,076s
sys 0m0,000s
faut lancer le script en direct via le shebang#!/usr/bin/python3, sinon :
$ time python bench_dec.py
real 0m5,051s
user 0m5,044s
sys 0m0,000s
;-)
Le calcul en décimal est performant (c'est assez normal), mais son usage me semble toujours bien limité pour en faire le comportement par défaut. Il ferait mieux d'ajouter une syntaxe particulière de littéraux pour eux, que d'en faire la solution par défaut et de rajouter des testes dynamiques pour savoir s'il faut changer de représentation (ce qui dégraderait encore plus les performances).
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
Par contre on peut pas nier que le débat s'est élevé grandement. On a sorti perl et python et on fait des essais.
Ça dépend du point de vue, pour moi le débat a régressé. Il n'était nul besoin de sortir perl ou python pour constater les résultats : les tests montrent juste ce que la théorie permettait déjà de savoir, et encore, avec des tests on ne prouve jamais autant de chose qu'avec une théorie bien faite (mais bon, malheureusement, il semblait falloir en passer par là pour te raisonner).
Ça me rappelle un ancien journal de rewind dans laquelle l'approche théorique avait été dénigrée, voire présentée comme inutile, par plus d'un intervenant. Je cite à nouveau le passage d'un ouvrage que j'avais cité à l'époque :
On appelle théorie un ensemble même de règles pratiques, lorsque ces règles sont conçues comme des principes ayant une certaine généralité, et que l'on y fait abstraction d'une foule de conditions qui pourtant exercent nécessairement de l'influence sur leur application. Réciproquement on ne donne pas le nom de pratique à toute espèce d'œuvre, mais seulement à la poursuite d'un but, quand on le considère comme l'observation de certains principes de conduite conçue d'une manière générale.
Il est évident qu'entre la théorie et la pratique il doit y avoir encore un intermédiaire qui forme le lien et le passage de l'une à l'autre, quelque complète d'ailleurs que puisse être la théorie. En effet, au concept de l'entendement, qui contient la règle, doit se joindre un acte du Jugement par lequel le praticien discerne si la règle s'applique ou non au cas présent ; et, comme on ne saurait toujours fournir au jugement des règles qui lui servent à se diriger dans ses subsomptions (puisque cela irait à l'infini), on conçoit qu'il y ait des théoriciens qui ne puissent jamais devenir praticiens de leur vie, parce qu'ils manquent de jugement : par exemple des médecins ou des jurisconsultes, qui ont fait d'excellentes études, mais qui, lorsqu'ils ont à donner un conseil, ne savent comment s'y prendre. En revanche, chez ceux qui possèdent ce don de la nature, il peut y avoir défaut de prémisses, c'est-à-dire que la théorie peut être incomplète, car peut-être a-t-elle besoin, pour être complétée, d'essais et d'expériences qui restent encore à faire; c'est de là que le médecin qui sort de son école, ou l’agriculteur, ou le financier, peut et doit abstraire de nouvelles règles pour compléter sa théorie. Ce n’est pas alors la faute de la théorie, si elle n’a encore que peu de valeur pour la pratique; cela vient de qu’on n’a pas assez de théorie, de celle que l’homme aurait dû apprendre de l’expérience, et qui est la véritable théorie, alors même que l’on n’est pas en état de la tirer de soi-même et de l’exposer systématiquement, comme un professeur, dans des propositions générales, et que par conséquent on ne saurait avoir aucune prétention au titre de médecin, d’agriculteur ou de financier théoricien. Personne ne peut donc se donner pour un praticien exercé dans une science et mépriser la théorie sans faire preuve d’ignorance dans sa partie; car c’est être vraiment ignorant que de croire que l’on peut dépasser la théorie en tâtonnant dans la voie des essais et des expériences, sans recueillir certains principes (qui constituent proprement ce que l’on nomme théorie) et sans faire de tout ce travail un ensemble (qui, méthodiquement traité, prend le nom de système).
Cependant on souffrira plus patiemment encore un ignorant qui, fier de sa prétendue pratique, déclare la théorie inutile et superflue, qu’un présomptueux qui la proclame bonne pour les écoles (comme une manière d’exercer l’esprit), mais qui soutient qu’il en va tout autrement dans la pratique; que, quand on quitte l’école pour le monde, on s’aperçoit qu’on n’a poursuivi jusque-là que des idées vides et des rêves philosophiques; en un mot que ce qui peut être bon dans la théorie n’a aucune valeur dans la pratique. (C’est ce que l’on exprime souvent aussi de cette manière: telle ou telle proposition est bonne in thesi, mais non in hypothesi.) Or on ne ferait que rire d’un mécanicien ou d’un artilleur empirique qui trancherait sur la mécanique générale ou sur la théorie mathématique de la projection des bombes, en disant que cette théorie, si ingénieusement conçue qu’elle soit, ne vaut rien dans la pratique, parce que, dans l’application, l’expérience donne de tout autres résultats que la théorie. (En effet, si à la première on ajoute la théorie du frottement, et à la seconde celle de la résistance de l’air, c’est-à-dire en général plus de théorie encore, elles s’accorderont parfaitement avec l’expérience.) Mais autre chose est une théorie qui concerne des objets d’intuition, autre chose une théorie dont les objets ne sont représentés qu’au moyen de concepts, comme les objets mathématiques et ceux de la philosophie. Peut-être ces derniers sont-ils susceptibles d'être conçus dans toute leur perfection (du côté de la raison), mais ne le sont-ils pas d'être donnés , et n'offrent-ils ainsi que des idées vides dont on ne saurait faire dans la pratique aucun usage ou qu'un usage dangereux. Par conséquent le proverbe en question pourrait bien avoir sa vérité dans les cas de ce genre. Mais dans une théorie qui est fondée sur le concept du devoir il n'y a plus lieu de craindre l'idéalité vide de ce concept; car ce ne serait pas un devoir de se proposer un certain effet de notre volonté, si cet effet n'était pas possible dans l'expérience (quelque parfaite ou quelque rapprochée de la perfection qu'on pût la concevoir). Or il n'est question dans le présent traité que de cette espèce de théorie.Il n'est pas rare d'entendre soutenir, au grand scandale de la philosophie, que ce qu'elle peut avoir d'exact ne vaut rien dans la pratique ; on dit cela sur un ton fort dédaigneux, en affichant la prétention de réformer la raison par l'expérience, même dans ce qui fait son principal titre de gloire, et en se flattant de voir plus loin et plus sûrement avec des yeux de taupe cloués sur la terre qu'avec ceux d'un être fait pour se tenir debout et regarder le ciel.
Sauf que changer un type de base qui est utilisé dans les binding C
Je ne vois pas où ils ont changé un type de base, ils ont juste changé la signature d'une fonction. Avant on avait :
intdiv(inti,intj)
maintenant on a :
floatdiv(inti,intj)
C'est juste le type de sortie d'une fonction qui a changé, non la représentation en mémoire d'un type de base. C'est un léger changement d'interface et de sémantique pour une fonction, avec une autre fonction existante (//) ayant le même comportement que l'ancienne, pas de quoi fouetter un chat ni jouer à l'équilibriste en haut d'un immeuble de 42 étages par vent de force 5. ;-)
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
Pour la question de l'absence de typage statique, c'est loin d'être le seul défaut de python.
Pour rester sur la question de la rigueur mathématique, de toute façon, pour moi, dès qu'on sort de la programmation fonctionnelle avec typage statique, on n'est déjà plus très rigoureux (je tolère à la rigueur les effets de bords et le code impure, c'est-à-dire les valeurs mutables, mais au-delà de ça, on est trop loin de la conception mathématique du calcul).
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
Je reviens à ce que je dis : s'il-te-plait, donne moi un avantage du float par rapport au Decimal mis à part la perfo.
Dès que l'on quitte les opérations algébriques de base (addition, multiplication, soustraction) et qu'on en vient aux fonctions transcendantes1 (sinus, cosinus, logarithme, exponentielle…, voir le commentaire de Michaël). Si tu reprends l'article de Guido sur les raisons du changements pour la division sur les int :
(This recently happened to me in a program that draws an analog clock – the positions of the hands were calculated incorrectly due to truncation, but the error was barely detectable except at certain times of day.)
Pour dessiner une horloge analogique, il faut faire de la trigonométrie et donc utilise les float. ;-)
même avec les nombres algébriques (racines de polynômes à coefficients entiers) cela devient vite injouable de calculer exactement et de les comparer. ↩
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
Je t'explique pas les problèmes de retro-compatibilité s'il fallait les interpréter par des décimaux :
type(2.3)<class'decimal.Decimal'>
il faudrait rajouter des float(...) partout dans le code existant :
type(float(2.3))<class'float'>
Ils n'ont pas déjà assez de problèmes avec le passage python 2.7 vers python 3 ?
Si tu veux des décimaux et gérer manuellement tes arrondis (et des problèmes d'arrondis, tu en auras), il y a un module pour cela : decimal. Si tu veux du calcul exact sur des fractions (sans problèmes d'arrondis avec les opérations algébriques), tu as un module pour cela : fractions. Sinon par défaut, comme dans tous les langages, tu te retrouves avec des nombres à virgule flottante ce qui n'est pas sans raison.
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
Merci de lire le 3e point de la page de la doc de Python. C'est exactement de ça dont je parle, c'est exactement la solution au problème exposé dans ce journal.
Eh bien ce que tu souhaites exactement (par défaut) est profondément ridicule. Quitte à choisir une représentation pour avoir de l'exactitude dans les calculs et perdre du temps (inutile dans la quasi totalité des applications), autant choisir celles des fractions : avec les décimaux tu n'as même pas la structure de corps (c'est pas « stable » par division comme type de données).
Maintenant que Python switche tout seul de l'int à l'IEEE quand il le juge bon, va-t-il un jour switcher de int à Decimal à IEEE quand il le juge bon ?
Et je t'ai répondu que ce n'est pas ce qu'il fait ! Il a juste changer la sémantique de l'opérateur / et son type de sortie. Avant / calculait le quotient euclidien et était de type int * int -> int, maintenant il calcule le résultat de la division en flottant et est de type int * int -> float. C'est juste un changement de sémantique (l'opérateur // étant là pour la division euclidienne) et non une adaptation au besoin de précision. Si vraiment, ils avaient voulu cela (ou s'ils le voulaient) il faudrait choisir le type Fraction en sortie et non le type Decimal.
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
C'est sûr que c'est pas très lisible pour un CM2. :-P
L'écriture est lié au système de typage statique OCaml qui n'a pas de mécanisme à la type classes de Haskell. Du coup 2 est toujours interpréter comme étant de type int et ~$ est juste une notation infixe pour la fonction of_int.
L'idée était surtout de montrer qu'il n'y avait aucune difficulté à faire du calcul formel sur les rationnels, avec pour seul limite la capacité mémoire de la machine (python le fait aussi) : c'est juste coûteux en mémoire et plus long en calcul, mais inutile dans la plupart des applications (d'où le recours aux flottants par défaut dans tous les langages).
>>>fromfractionsimportFraction>>># attention à bien utiliser des strings...Fraction('2')-Fraction('1.8')-Fraction('0.2')Fraction(0,1)>>># avec les floats sa posera aussi problème...Fraction(2)-Fraction(1.8)-Fraction(0.2)Fraction(-1,18014398509481984)>>>Fraction('3')*Fraction('5/3')Fraction(5,1)
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
Je me dis aussi que vu que Python le fait déjà dans un autre cas
C'est pas tout à fait cela, il a changé la sémantique d'un de ces opérateurs sur les int, à savoir l'opérateur /, qui avant calculait le quotient euclidien et qui maintenant calcule la division dans le type float (ce qui ne change pas les problèmes d'arrondis et l'impossibilité d'avoir une représentation finie en base 2 pour certaines fractions).
Si tu veux calculer formellement sur des fractions en python, il faut utiliser le module fractions.
>>>fromfractionsimportFraction>>># attention à bien utiliser des strings...Fraction('2')-Fraction('1.8')-Fraction('0.2')Fraction(0,1)>>>Fraction('3')*Fraction('5/3')Fraction(5,1)>>># avec les floats ça posera aussi problème...Fraction(2)-Fraction(1.8)-Fraction(0.2)Fraction(-1,18014398509481984)
Pour avoir un jour un tel comportement par défaut, j'en doute : les besoins en calcul formel sur ce type de nombres sont trop rares (application de niche) pour en faire le comportement par défaut.
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
Mon prof de math justement, t'aurais mis 0, tu n'as pas indiqué la précision.
Il écrit des nombres décimaux, ce sont des valeurs tout a fait acceptables dont on n'a pas besoin d'indiquer la précision (sinon on indique un intervalle).
#install_printerQ.pp_print;;Q.(of_ints23*of_ints34);;(* 2/3 * 3/4 = 1/2 *)-:Q.t=1/2Q.(of_string"2"-of_string"18/10"-of_string"2/10");;(* 2 - 1.8 - 0.2 = 0 *)-:Q.t=0Q.(of_int2-of_float1.8-of_float0.2);;(* avec les float ça marche pas *)-:Q.t=-1/18014398509481984
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
[^] # Re: Ne règle pas le "problème" du journa précédent
Posté par kantien . En réponse au journal Le retour de la vengeance de la virgule flottante. Évalué à 2.
Tu devrais ouvrir une entrée dans le suivi, ça ressemble à un problème d'interprétation du CSS (il y a des erreurs dans la mise en page et l'insertion des images correspondant aux formules LaTeX dans le texte).
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é à 6. Dernière modification le 22 janvier 2018 à 23:53.
Pas le temps de développer, mais on est bien obligé de tout ramener à des notions mathématiques : l'informatique ce n'est que des maths dans le fond. Cela étant, on ne fait pas abstraction du besoin de millions de codeurs : il existe des bibliothèques de calcul à virgule fixe ou virgule flottante en base 10 pour la plupart des langages. On dit juste que si tel est son besoin alors il faut les utiliser et non passer par des flottants en base 2.
Si le programmeur n'a pas utilisé les bons outils pour la tâche qui lui est assignée, c'est une faute professionnelle : il mérite une bonne volée de bois de vert de la part de ses supérieurs hiérarchiques (vu les conséquences de son erreur).
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é à 5.
Erreur de frappe, j'ai pensé réel et mes doigts ont écrit réelle. Mes doigts ils sont libres, un peu comme les pinceaux : l'autre jour je voulais peindre des enfants nus qui couraient dans un champ, à la fin je regarde la toile, et j'avais peint un pingouin ! :-P
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é à 8.
C'est bien ce qu'il me semblait. Et en plus il y a un troll caché sur les brevets d'algorithmes (que ce soit logiciel ou matériel, accepter un brevet sur des algorithmes faut vraiment pas être centré :-/).
Sinon, depuis l'autre journal je suis tombé sur une approche des plus intéressantes : la représentation par fractions continues. :-) Elle est décrite dans ce rapport de recherche INRIA : Arithmétique Réelle Exacte par Fractions Continues de Jean Vuillemin (il date tout de même de 1987 ;-). L'idée étant de représenter une fraction continue, possiblement infinie, de manière finie via une continuation : vive la programmation fonctionnelle ! :-)
L'article décrit la théorie : le corps des fractions continues et deux algorithmes pour les fonctions algébriques (fractions de polynômes) et les fonctions transcendantes (exponentielle, logarithme, fonctions trigonométriques et hyperboliques) basées sur des formules de Gauss, Legendre et Lambert. C'est une approche géométrique (un réelle comme produit d'homographies) particulièrement élégante, dont voici le résumé :
À l'époque Vuillemin en avait fait une implantation en LeLisp, mais il en existe une en Haskell présentée dans cette vidéo. Tu peux commencer par la vidéo, qui présente d'abord une autre bibliothèque Haskell basée sur une approche par intervalle en base 2 à la Cauchy1, puis décrit plus en détail l'approche par fractions continues.
Le code Haskell est assez court (cf le lien au-dessus). Il utilise des listes plutôt que des continuations car il tire partie de l'évaluation paresseuse de Haskell. Mais avec la bibliothèque Sequence de c-cube (qui a une approche par continuation) qui vient de sortir en version
1.0
combinée avec la bibliothèque Zarith, on doit pouvoir faire cela facilement en OCaml.j'ai d'ailleurs été étonné que l'orateur ait du expliquer à son auditoire ce qu'était une suite de Cauchy. :-o ↩
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
[^] # Re: 300^4 = 8100000000
Posté par kantien . En réponse au journal Générateur de mot de passe. Évalué à 4.
De rien. La prochaine fois que tu veux calculer une entropie de mot passe, si tu n'as pas en tête les puissances de 2, tu sors ton python et tu fais :
voilà, l'entropie avec tes listes est de
41.76
. ;-)Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
[^] # Re: 300^4 = 8100000000
Posté par kantien . En réponse au journal Générateur de mot de passe. Évalué à 4.
L'entropie est de l'ordre de 40 bits.
143 ~ 2^7
,1977 ~ 2^11
et304 ~ 2^8
, d'où un couple adjectif+nom donne une entropie de l'ordre de 15 (=7 + 8
) bits, deux tels couples donnent une entropie de 30, plus les 11 pour le verbe, on arrive aux alentours de 40 (du même ordre que dans le xkcd : 4 parmi2^11
possibilités soit4 * 11 = 44
bits d'entropie).Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
[^] # Re: Commentaire de soutien ;-)
Posté par kantien . En réponse au journal [Humour] vers un monde différent. Évalué à 3.
La norme IEEE-754 respecte très bien la vérité mathématique, mais j'y reviendrais après.
Bien au contraire ! C'est un très bon prétexte pour leur faire travailler leurs mathématiques. :-)
Je m'explique en illustrant par une approche possible (je ne suis pas là pour produire du matériel d'enseignement) en partant de ce que les élèves maîtrisent bien : la base
10
(et c'est cela qui choque dans l'exemple du journal).Là je ne fais que charger de quoi travailler avec des nombres flottants en base
10
: des décimaux, en somme; et je fixe une précision assez basse pour avoir de petits nombres.Hop, on définit les nombres
1, 2, 3
et on fait quelques calculs avec. On voit un peu à quoi correspondait lectx.prec = 3
de tout à l'heure (pour l'instant, c'est le chiffre de nombre après la virgule). Le résultat de la première opération doit être familière à tout lycéen : il sait que si l'on divise1
par3
, il aura une infinité de3
après la virgule et là il n'en garde que trois.Pour la seconde opération, il sait très bien que
2 * 333 = 666
d'où2 * 0.333 = 0.666
. La fraction a était approximée avant la multiplication, mais ensuite le calcul de celle-ci est on ne peut plus conforme à la « vérité mathématique » (qui te tient tant à cœur). En revanche si l'on pratique directement la division de2
par3
, puis que l'on approxime au plus proche en ne conservant que trois chiffres après la virgule, on obtient un autre résultat, à savoir0.667
.On peut continuer et montrer quelques « étrangetés » (qui n'en seront sans doute pas pour des lycéens) du calcul selon les règles strictes de l'arithmétique mais avec des arrondis.
Et là c'est tout à fait compréhensible. Selon les règles strictes de l'arithmétique, on a bien
, là où
.
333 + 333 + 333 = 3 * 333 = 999
. Et pour le dernier, on a bien333 + 667 = 1000
ou dans notre cas0.333 + 0.667 = 1.000
, mais comme la précision est de3
il n'affiche que1.00
. En fait la précision c'est la taille de la mantisse, c'est à dire que le nombre est vu commeun /trois
est vu commeIllustration du changement de précision :
Il me semble bien que tout ce qui précède est largement accessible à des lycéens. Il suffit ensuite de développer la chose en leur expliquant que le même genre de phénomène se produit si l'on prend une base
2
au lieu d'une base10
, et que c'est dans cette base que travaille python par défaut.Les deux « erreurs » de calcul relèvent des mêmes principes mathématiques mais dans deux bases distinctes.
Pour revenir, et conclure, sur cette histoire de standard IEEE. Le calcul flottant en base
2
a été normalisé en 1985 sous le nom de standard IEEE-7554. En 2008, y a été ajouté une normalisation de la base 10 (utilisée ici par Python), et j'avais donné plus haut le lien vers la page de l'ingénieur IBM qui s'en est occupé. Python datant de 1990, les matériels ayant implanté le standard de 1985 dans leur FPU, on peut comprendre pourquoi, par défaut, ce langage utilise la base2
et non la base10
.Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
[^] # Re: Commentaire de soutien ;-)
Posté par kantien . En réponse au journal [Humour] vers un monde différent. Évalué à 3.
Il n'y avait aucune agressivité dans mon commentaire, je ne faisais que résumer ce qui a été dit mainte et mainte fois au cours du fil.
Oui, et cela est vrai même en arithmétique flottante quelque soit la base
x - x
vaut toujours0
, même en informatique « biaisée ».Non, c'est juste le moyen d'avoir accès à de l'arithmétique flottante en base 10, qui est celle que l'on a apprise au primaire. Par défaut les littéraux flottants sont calculés en base 2 en Python (comme dans de nombreux langage). Tu peux toujours utiliser Haskell si tu veux du polymorphisme ad-hoc sur les littéraux flottants.
Infirmation ;-)
renvoie
Voir la référence sur les constantes en Go.
Je ne te le fais pas dire. ;-)
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
[^] # Re: Commentaire de soutien ;-)
Posté par kantien . En réponse au journal [Humour] vers un monde différent. Évalué à 3.
Dans aucun, même dans l'arithmétique flottante en base 2 (en excluant les infinis, bien sûr ;-).
Le principe de l'arithmétique flottante est de traiter des nombres de la forme :
Ce qu'il y a c'est que par défaut, python utilise la base
2
pour traiter les nombres à virgules, conformément à la norme IEEE-754, et que certains nombres décimaux ne sont pas représentables de manière finie dans une telle base (comme0.2
). Néanmoins cette norme a été révisée en 2008 pour y inclure également l'arithmétique flottante en base10
(ce qu'implémente le moduledecimal
depython
) mais elle ne bénéficie pas d'accélération matériel (sauf chez des processeurs utilisés en autres dans la finance : SPARC64, POWER PC (Power 6), IBM System Z9).Non, on te dit d'utiliser le module
decimal
, il est fait pour cela. ;-)Cela étant, en base 10 tu auras des problèmes similaires de nombres non représentables, et même en base
2
il faut juste savoir écrire ses opérations :Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
[^] # Re: Petit résumé et tests dans la réalité
Posté par kantien . En réponse au journal [Humour] vers un monde différent. Évalué à 4.
Rien n'est moins sûr. Le modèle d'exécution de python est bien différent de celui du C.
Là, je fais
100
boucles avec10_000
multiplication par boucles.Le temps de la boucle est négligeable et le facteur est toujours de
2
.Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
[^] # Re: Pas la musique…
Posté par kantien . En réponse au journal [Humour] vers un monde différent. Évalué à 2.
Arthur n'a pas tort, le ton est monté inutilement et je te trouve bien agressif également dans ta manière d'intervenir (depuis un moment déjà dans ce journal).
Je pense n'avoir rien à apprendre en mathématique de ta part (peut être en analyse numérique, mais c'est vraiment un domaine qui ne m'a jamais passionné, je trouve cela ennuyeux à mourir), et déjà sur le journal de Blackknight sur le décalage de 64 bits, tu avais tendance à monter sur tes grands chevaux. J'avais tenter, sans succès, de désamorcer la chose par l'humour avec Homer et sa théorie de l'univers en forme de beignet, pour la simple raison que quand je multiplie deux cercles j'obtiens un beignet (la géométrie algébrique, c'est bon mangez-en :-). Et c'est cette structure géométrique (le beignet) qui m'avais permis d'identifier les points pathologiques dans la plupart des langages qui ont fait ce choix (plutôt que le cylindre, produit d'un cercle par un segment, comme Ada) pour des raison de performances sur les X86 (ça évite des tests dynamiques à l'exécution). ;-)
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
[^] # Re: Petit résumé et tests dans la réalité
Posté par kantien . En réponse au journal [Humour] vers un monde différent. Évalué à 3.
Il doit y avoir une erreur dans ton installation de python. Là tu nous sors l'implémentation en pure python, là où normalement tu devrais avoir une implémentation en C du module. Que te réponds cette commande :
Ça reste moins performant que des
float
(ce qui était prévisible) mais pas dans de telle proportion. Pour un comparatif avec des benchs plus précis, voir le site de libmpdec (c'est plutôt du simple au double pour les opérations de bases : addition, multiplication, division).Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
[^] # Re: Petit résumé et tests dans la réalité
Posté par kantien . En réponse au journal [Humour] vers un monde différent. Évalué à 2. Dernière modification le 23 décembre 2017 à 00:27.
faut lancer le script en direct via le shebang
#!/usr/bin/python3
, sinon :;-)
Le calcul en décimal est performant (c'est assez normal), mais son usage me semble toujours bien limité pour en faire le comportement par défaut. Il ferait mieux d'ajouter une syntaxe particulière de littéraux pour eux, que d'en faire la solution par défaut et de rajouter des testes dynamiques pour savoir s'il faut changer de représentation (ce qui dégraderait encore plus les performances).
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
[^] # Re: Petit résumé et tests dans la réalité
Posté par kantien . En réponse au journal [Humour] vers un monde différent. Évalué à 3.
Ça dépend du point de vue, pour moi le débat a régressé. Il n'était nul besoin de sortir perl ou python pour constater les résultats : les tests montrent juste ce que la théorie permettait déjà de savoir, et encore, avec des tests on ne prouve jamais autant de chose qu'avec une théorie bien faite (mais bon, malheureusement, il semblait falloir en passer par là pour te raisonner).
Ça me rappelle un ancien journal de rewind dans laquelle l'approche théorique avait été dénigrée, voire présentée comme inutile, par plus d'un intervenant. Je cite à nouveau le passage d'un ouvrage que j'avais cité à l'époque :
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
[^] # Re: Puisque tout le monde est sûr de détenir la vérité...
Posté par kantien . En réponse au journal [Humour] vers un monde différent. Évalué à 2. Dernière modification le 22 décembre 2017 à 17:21.
Je ne vois pas où ils ont changé un type de base, ils ont juste changé la signature d'une fonction. Avant on avait :
maintenant on a :
C'est juste le type de sortie d'une fonction qui a changé, non la représentation en mémoire d'un type de base. C'est un léger changement d'interface et de sémantique pour une fonction, avec une autre fonction existante (
//
) ayant le même comportement que l'ancienne, pas de quoi fouetter un chat ni jouer à l'équilibriste en haut d'un immeuble de 42 étages par vent de force 5. ;-)Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
[^] # Re: Puisque tout le monde est sûr de détenir la vérité...
Posté par kantien . En réponse au journal [Humour] vers un monde différent. Évalué à 2.
Non, juste redéfinir une fonction sur un type de base. Je n'appelle pas cela changer tout le langage. ;-)
Pour la question de l'absence de typage statique, c'est loin d'être le seul défaut de python.
Pour rester sur la question de la rigueur mathématique, de toute façon, pour moi, dès qu'on sort de la programmation fonctionnelle avec typage statique, on n'est déjà plus très rigoureux (je tolère à la rigueur les effets de bords et le code impure, c'est-à-dire les valeurs mutables, mais au-delà de ça, on est trop loin de la conception mathématique du calcul).
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
[^] # Re: Puisque tout le monde est sûr de détenir la vérité...
Posté par kantien . En réponse au journal [Humour] vers un monde différent. Évalué à 4.
Dès que l'on quitte les opérations algébriques de base (addition, multiplication, soustraction) et qu'on en vient aux fonctions transcendantes1 (
sinus, cosinus, logarithme, exponentielle
…, voir le commentaire de Michaël). Si tu reprends l'article de Guido sur les raisons du changements pour la division sur lesint
:Pour dessiner une horloge analogique, il faut faire de la trigonométrie et donc utilise les
float
. ;-)même avec les nombres algébriques (racines de polynômes à coefficients entiers) cela devient vite injouable de calculer exactement et de les comparer. ↩
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
[^] # Re: Rien de surprenant
Posté par kantien . En réponse au journal [Humour] vers un monde différent. Évalué à 5.
C'est même pire que ce que tu crois, il faudrait changer également l'inteprétation des littéraux.
Je t'explique pas les problèmes de retro-compatibilité s'il fallait les interpréter par des décimaux :
il faudrait rajouter des
float(...)
partout dans le code existant :Ils n'ont pas déjà assez de problèmes avec le passage
python 2.7
verspython 3
?Si tu veux des décimaux et gérer manuellement tes arrondis (et des problèmes d'arrondis, tu en auras), il y a un module pour cela :
decimal
. Si tu veux du calcul exact sur des fractions (sans problèmes d'arrondis avec les opérations algébriques), tu as un module pour cela :fractions
. Sinon par défaut, comme dans tous les langages, tu te retrouves avec des nombres à virgule flottante ce qui n'est pas sans raison.Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
[^] # Re: Rien de surprenant
Posté par kantien . En réponse au journal [Humour] vers un monde différent. Évalué à 7.
Eh bien ce que tu souhaites exactement (par défaut) est profondément ridicule. Quitte à choisir une représentation pour avoir de l'exactitude dans les calculs et perdre du temps (inutile dans la quasi totalité des applications), autant choisir celles des fractions : avec les décimaux tu n'as même pas la structure de corps (c'est pas « stable » par division comme type de données).
Et je t'ai répondu que ce n'est pas ce qu'il fait ! Il a juste changer la sémantique de l'opérateur
/
et son type de sortie. Avant/
calculait le quotient euclidien et était de typeint * int -> int
, maintenant il calcule le résultat de la division en flottant et est de typeint * int -> float
. C'est juste un changement de sémantique (l'opérateur//
étant là pour la division euclidienne) et non une adaptation au besoin de précision. Si vraiment, ils avaient voulu cela (ou s'ils le voulaient) il faudrait choisir le typeFraction
en sortie et non le typeDecimal
.Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
[^] # Re: Ca marche aussi... Mais j'ai triché
Posté par kantien . En réponse au journal [Humour] vers un monde différent. Évalué à 2.
C'est sûr que c'est pas très lisible pour un CM2. :-P
L'écriture est lié au système de typage statique OCaml qui n'a pas de mécanisme à la type classes de Haskell. Du coup
2
est toujours interpréter comme étant de typeint
et~$
est juste une notation infixe pour la fonctionof_int
.L'idée était surtout de montrer qu'il n'y avait aucune difficulté à faire du calcul formel sur les rationnels, avec pour seul limite la capacité mémoire de la machine (python le fait aussi) : c'est juste coûteux en mémoire et plus long en calcul, mais inutile dans la plupart des applications (d'où le recours aux flottants par défaut dans tous les langages).
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
[^] # Re: Rien de surprenant
Posté par kantien . En réponse au journal [Humour] vers un monde différent. Évalué à 5. Dernière modification le 20 décembre 2017 à 12:31.
C'est pas tout à fait cela, il a changé la sémantique d'un de ces opérateurs sur les
int
, à savoir l'opérateur/
, qui avant calculait le quotient euclidien et qui maintenant calcule la division dans le typefloat
(ce qui ne change pas les problèmes d'arrondis et l'impossibilité d'avoir une représentation finie en base 2 pour certaines fractions).Si tu veux calculer formellement sur des fractions en python, il faut utiliser le module fractions.
Pour avoir un jour un tel comportement par défaut, j'en doute : les besoins en calcul formel sur ce type de nombres sont trop rares (application de niche) pour en faire le comportement par défaut.
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
[^] # Re: Ca marche aussi... Mais j'ai triché
Posté par kantien . En réponse au journal [Humour] vers un monde différent. Évalué à 3. Dernière modification le 20 décembre 2017 à 00:05.
Avec Zarith et la précision arbitraire sur les entiers et les rationnels, on résout le problème du journal :
mais aussi celui d'un de tes anciens journaux ;-)
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
[^] # Re: Rien de surprenant
Posté par kantien . En réponse au journal [Humour] vers un monde différent. Évalué à 2.
Oui, je l'ai trouvé après le pretty-printer. Je l'ai mis dans cet autre commentaire et celui-ci. C'est plus joli avec. ;-)
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
[^] # Re: Ca marche aussi... Mais j'ai triché
Posté par kantien . En réponse au journal [Humour] vers un monde différent. Évalué à 3.
mais les rationnels, eux, forment un corps :
:-)
et pour ceux qui aiment les grandes puissances :-P
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
[^] # Re: Rien de surprenant
Posté par kantien . En réponse au journal [Humour] vers un monde différent. Évalué à 6.
Il écrit des nombres décimaux, ce sont des valeurs tout a fait acceptables dont on n'a pas besoin d'indiquer la précision (sinon on indique un intervalle).
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.