-
Sujet
-
Bonjour,
un truc un peu énervant avec python que vous aurez peut être remarqué :
si vous allez sur un shell et que vous tapez : 0.1+0.1+0.1
Vous vous attendez à avoir un 0.3 en résultat…
Pourtant, on obtiendra en résultat : 0.30000000000000004
Et ca n’est pas le seul langage à faire cela ! Si vous appuyez sur F12 et que vous allez dans votre console javascript. En tapant 0.1+0.1+0.1, vous obtiendrez à nouveau ce nombre…
Bon… pour le C si vous faites ca, vous n’aurez pas le même résultat parce que le C affiche moins de chiffres après la virgules.
Mais si on fait :
#include <stdio.h> int main() { float t; for (int i=0; i<1000; i++){ t+=0.1f; } printf("value is : %f", t); return 0; }
On obtient : 99.999046
AHAH !
(Bon en vérité le C a plus de chances parce qu’en mettant un double à la place d’un float (avec tous les changements que cela implique, le %f devient %lf et le t+=0.1f devient t+=0.1), le programme n’a plus de problème mais ceux ci reviennent avec des valeurs beaucoup plus hautes dans la boucle for… ainsi, pour 1000000, j’ai obtenu 100000.000001. Il ne faut pas oublié de plus que le printf affichait beaucoup moins de chiffres que le print.)
Mais qu’est ce que ca nous apprend le fait qu’en C, entre float et double (deux types pour les nombres à virgules), l’endroit ou l’erreur se produit n’est pas au même endroit ?
Ca nous apprend que c’est une question de précision car les float ont une taille de 32 bits (4 octets) et les doubles de 64 bits (8 octets).
C’est d’ailleurs ce que nous apprend ce site : https://docs.python.org/fr/2.7/tutorial/floatingpoint.html
En réalité, les nombres float que l’on voit en python ne sont que des approximations. On peut voir ces approximations avec (copié collé du dernier site 🙂 ) :
>>> from decimal import Decimal >>> Decimal(2.675) Decimal('2.67499999999999982236431605997495353221893310546875') #C'est comme ca que le nombre est stocké en mémoire.. python nous donne simplement un arrondi
Mais parfois, les arrondis échouent à livrer le bon résultat…
La solution ?
Il existe une librairie qui s’appelle fractions avec une classe Fraction définie à l’intérieur. Elle prend en paramètre à sa création un numérateur et un dénominateur.
>>> from fractions import * >>> a = Fraction(1, 10) + Fraction(1, 10) + Fraction(1, 10) >>> a Fraction(3, 10) >>> float(a) 0.3
Voilà j’espère que ca vous aura intéressé ! Je ne suis pas du tout rentré dans les détails parce que.. ca n’est qu’un post sur un forum mais je vous invite à chercher un peu plus à ce sujet parce que j’ai éclipsé de nombreuses choses à ce sujet et c’est très intéressant !
- Vous devez être connecté pour répondre à ce sujet.