LINUX.ORG.RU

Баг остатка от деления в python 2.7.2

 


0

1

Заметил тут интереснейший баг/фичу, и хочу спросить у остальных, то что показано ниже давно известный баг и в python 3 его починили?

t=0
for i in range(30):
    t=t+0.1
    print "t=",t," t%1.0= ",t % 1.0, "  t-t/1.0 =",t-t//1.0

Вот вывод

t= 0.8  t%1.0=  0.8   t-t/1 = 0.8
t= 0.9  t%1.0=  0.9   t-t/1 = 0.9
t= 1.0  t%1.0=  1.0   t-t/1 = 1.0
t= 1.1  t%1.0=  0.1   t-t/1 = 0.1
t= 1.2  t%1.0=  0.2   t-t/1 = 0.2
t= 1.8  t%1.0=  0.8   t-t/1 = 0.8
t= 1.9  t%1.0=  0.9   t-t/1 = 0.9
t= 2.0  t%1.0=  4.4408920985e-16   t-t/1 = 4.4408920985e-16
t= 2.1  t%1.0=  0.1   t-t/1 = 0.1

Просьба писать свои версии python и результаты, мнение о том стоит ли оформлять багрепорт, и как с этим справиться

★★★★★

Так в python 3 этого безобразия нет

DR_SL ★★★★★
() автор топика
Ответ на: комментарий от catap

Прошу прощения, просто я в попыхах, переношу код из octave.

Мне нужно сделать преобразование типов?

t=float(t)?

Строчка выше не помогла(

DR_SL ★★★★★
() автор топика
Ответ на: комментарий от DR_SL

Это проблема _представления_, то есть некритично:

value 0.100000000000000005551115123125. In versions prior to Python 2.7 and Python 3.1, Python rounded this value to 17 significant digits, giving ‘0.10000000000000001’. In current versions, Python displays a value based on the shortest decimal fraction that rounds correctly back to the true binary value, resulting simply in ‘0.1’.

http://docs.python.org/tutorial/floatingpoint.html

Оборачивайте при выводе в str, например.

anonymous
()
Ответ на: комментарий от anonymous

Пардон, недосмотрел, это особый случай ieee754, denormalized вроде. (Можно при выводе округлять до 15, если так не пригоже).

anonymous
()
Ответ на: комментарий от anonymous

Уже голова совсем не бум бум Пробовал

str(Decimal("%.16f" % t )%Decimal("1"))

Так что нужно сделать в 2,7? мне бы ъотябы эту единицу до e-2 свести, дальше round добьет

DR_SL ★★★★★
() автор топика

Причем здесь питон вообще? На Сях ,будет все то же самое.

Когда Вы считаете t (в цикле), при сложениях накапливается ошибка в посл знаке, которая потом и стреляет, в последнем же знаке.

t = 0
for i in range(20) : t += .1
print t, repr(t)
2.0 2.0000000000000004

считайте t по другому, и будет Вам щастье

t = .1*20
print t, repr(t)
2.0 2.0
print t%1., t-t//1.
0.0 0.0

или округляйте до нужного знака ф-ей round:

t = 2.0000000000000004
round( t, 14 )%1.
0.0
#или
round( е%1., 15 )
0.0

AIv ★★★★★
()
Ответ на: комментарий от DR_SL

В Питоне есть также модуль decimal с полностью десятичной арифметикой произвольной точности, все результаты как на настольном калькуляторе :-)

capricorn20
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.