Найти - Пользователи
Полная версия: round() в python 2.6
Начало » Python для новичков » round() в python 2.6
1 2 3
Андрей Светлов
Да не в round дело. Python 2.7 использует другой алгоритм для преобразования float в str. Вот и получается разный вывод для одних и тех же чисел.
Сам round не изменился и работает как и прежде.
Isem
Ну тогда уж так (если принимать во внимание количество требуемых цифр после запятой):
def round( num, dig ):
dec = 10**dig
return int(num*dec+0.5)/dec
Subideal Ox
Ставим эксперимент:
import sqlite3
con = sqlite3.connect('test.sqlite3')
cur = con.cursor()
cur.execute('create table if not exists test (x)')
cur.execute('insert into test(x) values (?)', (round(4.3111111, 2),))
cur.execute('select * from test')
for row in cur: print row
con.commit()
con.close()
Out:
(4.3099999999999996,)
Реакция: Обман! Это и есть тот самый хваленый питон на который я сменил свой php (basic, калькулятор citizen)?! Что за фигня?! … Кто-то может это объяснить? И как-то можно питона заставить округлять число корректно?

Заходим с другой стороны (из оболочки):
ox@blackstar:~$ sqlite3 test.sqlite3
SQLite version 3.6.22
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> select * from test
...> ;
4.31
sqlite>
Э-э-э… Чудо? Чудо! Аллилуйа!

Должная реакция: Думаем. Думаем еще раз. Извиняемся за слова:

Isem
Вы сами то поняли, что сказали? Вы путаете три вещи: …
Каллиграфическим подчерком выписываем слова гуру:

Андрей Светлов
Вы различаете двоичную запись и текстовое представление для float?
И то, что многие дроби можно записать двумя способами, 4.31 одна из них?
Медитируем над бумажкой три дня и торжественно обещаем никогда не морочить коллегам голову самодельными round.

:D
regall
Кстати, то что 4.309(9) = 4.31 доказывается методом математической индукции. Помню это еще в школе в 10-м классе учили. Это так, к слову.
Isem
Subideal Ox
Медитируем над бумажкой три дня и торжественно обещаем никогда не морочить коллегам голову самодельными round.
Бумажку желательно перед этим хорошенько размять :)
Потому что sql сам умеет округлять на выходе, а
Subideal Ox
Это и есть тот самый хваленый питон
и
Андрей Светлов
The disadvantage is that many people found the output to be confusing (mistaking intrinsic limitations of binary floating point representation as being a problem with Python itself).
Имеем конфуз.
Isem
regall
Кстати, то что 4.309(9) = 4.31 доказывается методом математической индукции.
Может быть дедукции?
Андрей Светлов
Нет, всё же это именно “математическая индукция”: http://ru.wikipedia.org/wiki/%D0%9C%D0%B0%D1%82%D0%B5%D0%BC%D0%B0%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B0%D1%8F_%D0%B8%D0%BD%D0%B4%D1%83%D0%BA%D1%86%D0%B8%D1%8F
Isem
Андрей Светлов
Нет, всё же это именно “математическая индукция”: http://ru.wikipedia.org/wiki/%D0%9C%D0% … 0%B8%D1%8F
Значит Конан Дойль ошибся.
Subideal Ox
Isem
Может быть дедукции?
А парень не сдается! :D Молодец, гасконец. Так держать!

Предлагаю следующий эксперимент:

1. На машине с python 2.6 создать переменную a = round(4.3111111, 2). Вывести ее на экран. Увидеть 4.3099999999999996. Сделать pickle на диск. Загрузить число из пикла обратно. Вывести на экран. Увидеть 4.3099999999999996. Злорадно потереть руки.
2. Отправить пикл другу с python 2.7. Попросить его загрузить этот пикл. На экране он увидит 4.31. Удивиться.
3. На машине с python 2.7 создать переменную a = round(4.3111111, 2). Вывести ее на экран. Увидеть 4.31. Сделать pickle на диск. Загрузить число из пикла обратно. Вывести на экран. Увидеть 4.31. Задуматься.
4. Попросить отправить второй пикл обратно на машину с python 2.6. Загрузить пикл. Вывести. Увидеть 4.3099999999999996. Удивиться. Подумать. Раскаяться.

Ну и далее по тексту со слов ‘Э-э-э… Чудо? Чудо! Аллилуйа!’ в моем предыдущем посте.

;D
Isem
Давайте споим себя, что делает pickle? Правильно, он записывает 8 байт (само число) и “окружение”. Это число имеет (эти самые 64 бита) одинаковый вид что в питоне 2.7, что 2.6, что 1.7, что 3.1, потому что это IEEE. И что же у нас получается? Разные представления одного и того же числа! (боже мой).
Subideal Ox
А парень не сдается! Молодец, гасконец. Так держать!
А что мне еще остается делать?

p.s. вместо споим читаем: спросим
p.s.s. это очень актуально получилось
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB