2015-08-17 2 views
3

Когда я пытаюсь проверить, содержит ли переменная float точное целочисленное значение, я получаю следующее странное поведение. Мой код:Python float и int поведение

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)) 

Я получаю на следующие странный вывод (последняя строка проблемы):

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

Любая идея, почему 2.0 является true и 3.0 является false?

+0

[Это относится чтение из документации.] (https://docs.python.org/2/tutorial/ floatingpoint.html) – SuperBiasedMan

+1

[Является ли математика с плавающей запятой?] (Http://stackoverflow.com/q/588004/995714). http://floating-point-gui.de/, [Что каждый компьютерный ученый должен знать о арифметике с плавающей точкой] (http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) –

ответ

10

проблема не с конверсией, но с добавление.

int(3.0) == 3.0 

возвращает Истинные

, как и ожидалось.

probelm является то, что плавающие точки не бесконечно точны, и вы не можете ожидать 2,7 + 0,1 * 3 будет 3,0

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

По предложению @SuperBiasedMan стоит отметить, что в OPs подход к проблеме был как-то скрыт в связи с использованием полиграфического (строка преобразования), который упрощает представление данных, чтобы максимизировать читаемость

>>> 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

Стоит отметить, что различие не показано четко, потому что 'print' будет игнорировать несоответствие ради удобочитаемости, но если вы будете использовать' repr (2.7 + 0.1 + 0.1 + 0.1) ', он будет показывать истинное значение. – SuperBiasedMan

+1

** Исправление ** Более точное значение, оно все равно будет игнорировать определенное количество знаков после запятой. – SuperBiasedMan

Смежные вопросы