2015-08-03 2 views
0

Я хотел бы протестировать набор из 3 переменных w1,w2,w3. Когда сумма их равна 1, я хочу напечатать "YATTA".Проблема с поплавком с использованием arange() from numpy

import numpy as np 

for w1 in np.arange(0.10,0.45,0.05): 
     for w2 in np.arange(0.10,0.45,0.05): 
      for w3 in np.arange(0.10,0.45,0.05): 
       sumw=w1+w2+w3 
       if(sumw==1.0): 
        print "YATTA" 
       else: 
        print w1,w2,w3,sumw 

Когда я запускаю это, я наблюдаю что-то очень странное! Например, когда мои переменные:

w1 = 0.2 
w2 = 0.4 
w3 = 0.4 

sumw составляет 1,0 НО он не печатает "YATTA" и вместо else выполняется оператор.

Почему мой код ведет себя так и как я могу решить эту проблему?

+2

[Добро пожаловать в мир арифметики с плавающей точкой.] (Http://docs.oracle .com/cd/E19957-01/806-3568/ncg_goldberg.html) –

+0

Это должно быть дубликат, подобные вопросы задаются все время. –

ответ

3

Похоже, вы ошиблись в том, что арифметика с плавающей запятой не является точной.

См. this question за хорошее объяснение, почему вы получаете результаты, которые вы есть.

быстрое описание пояснение вашего конкретного случая состоит в том, что ваши десятичные знаки не могут быть преобразованы точно в двоичные файлы, так что w1, w2 и w3 не совсем то, что вы думаете. В более общем плане: большинство реальных чисел не могут быть представлены в конечном числе цифр, и большинство операций с плавающей запятой должны иметь округление.

Как исправить, вместо сравнения поплавков равенства, как вы делаете сейчас, вместо того, чтобы использовать np.isclose функции вместо

np.isclose(sumw, 1.0)