2015-08-17 2 views
3

lorsque je tente de vérifier si la variable flottante contient la valeur entière exacte i obtenir le comportement étrange folowing. Mon code:comportement float et int Python

x = 1.7 print x, (x == int(x)) 
x += 0.1 print x, (x == int(x)) 
x += 0.1 print x, (x == int(x)) 
x += 0.1 print x, (x == int(x)) 
print "----------------------" 

x = **2.7** print x, (x == int(x)) 
x += 0.1 print x, (x == int(x)) 
x += 0.1 print x, (x == int(x)) 
x += 0.1 print x, (x == int(x)) 

je reçois la sortie étrange folowing (dernière ligne est le problème):

1.7 False 
1.8 False 
1.9 False 
2.0 True 
---------------------- 
2.7 False 
2.8 False 
2.9 False 
3.0 False 

Toute idée pourquoi 2.0 est true et 3.0 est false?

+0

[Ceci est la lecture pertinente des documents.] (https://docs.python.org/2/tutorial/ floatingpoint.html) – SuperBiasedMan

+1

[Le calcul à virgule flottante est-il rompu?] (http://stackoverflow.com/q/588004/995714). http://floating-point-gui.de/, [Ce que tout informaticien doit savoir sur Arithmétique à virgule flottante] (http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) –

Répondre

10

le problème est pas avec la conversion, mais avec plus.

int(3.0) == 3.0 

retours vrai

comme prévu.

Le gros problème est que les points flottants ne sont pas infiniment précis, et vous ne pouvez pas attendre 2,7 + 0,1 * 3 pour être 3,0

>>> 2.7 + 0.1 + 0.1 + 0.1 
3.0000000000000004 
>>> 2.7 + 0.1 + 0.1 + 0.1 == 3.0 
False 

Comme suggéré par @SuperBiasedMan il convient de noter que, dans OPs approche le problème en quelque sorte caché en raison de l'utilisation de l'impression (conversion de chaîne) qui simplifie la représentation des données pour optimiser la lisibilité

>>> print 2.7 + 0.1 + 0.1 + 0.1 
3.0 
>>> str(2.7 + 0.1 + 0.1 + 0.1) 
'3.0' 
>>> repr(2.7 + 0.1 + 0.1 + 0.1) 
'3.0000000000000004' 
+3

a noter que la distinction n'apparaît pas clairement parce que 'print' ignoreront l'écart pour des raisons de lisibilité, mais si vous deviez utiliser' rééd (2,7 + 0,1 + 0,1 + 0,1) 'il montrerait la valeur réelle. – SuperBiasedMan

+1

** Correction ** Une valeur plus précise, il ignorera encore un certain nombre de décimales. – SuperBiasedMan