Уведомления

Группа в Telegram: @pythonsu

#1 Фев. 4, 2011 22:13:41

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

round() в python 2.6

Да не в round дело. Python 2.7 использует другой алгоритм для преобразования float в str. Вот и получается разный вывод для одних и тех же чисел.
Сам round не изменился и работает как и прежде.



Офлайн

#2 Фев. 4, 2011 22:21:25

Isem
От:
Зарегистрирован: 2010-08-27
Сообщения: 447
Репутация: +  7  -
Профиль   Отправить e-mail  

round() в python 2.6

Ну тогда уж так (если принимать во внимание количество требуемых цифр после запятой):

def round( num, dig ):
dec = 10**dig
return int(num*dec+0.5)/dec



Офлайн

#3 Фев. 4, 2011 23:08:02

Subideal Ox
От:
Зарегистрирован: 2010-11-23
Сообщения: 65
Репутация: +  0  -
Профиль   Отправить e-mail  

round() в python 2.6

Ставим эксперимент:

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



Офлайн

#4 Фев. 4, 2011 23:12:48

regall
От: Киев
Зарегистрирован: 2008-07-17
Сообщения: 1583
Репутация: +  3  -
Профиль   Отправить e-mail  

round() в python 2.6

Кстати, то что 4.309(9) = 4.31 доказывается методом математической индукции. Помню это еще в школе в 10-м классе учили. Это так, к слову.



Офлайн

#5 Фев. 4, 2011 23:16:53

Isem
От:
Зарегистрирован: 2010-08-27
Сообщения: 447
Репутация: +  7  -
Профиль   Отправить e-mail  

round() в python 2.6

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).
Имеем конфуз.



Офлайн

#6 Фев. 4, 2011 23:18:18

Isem
От:
Зарегистрирован: 2010-08-27
Сообщения: 447
Репутация: +  7  -
Профиль   Отправить e-mail  

round() в python 2.6

regall
Кстати, то что 4.309(9) = 4.31 доказывается методом математической индукции.
Может быть дедукции?



Офлайн

#7 Фев. 4, 2011 23:26:18

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

round() в python 2.6

Офлайн

#8 Фев. 4, 2011 23:29:05

Isem
От:
Зарегистрирован: 2010-08-27
Сообщения: 447
Репутация: +  7  -
Профиль   Отправить e-mail  

round() в python 2.6

Андрей Светлов
Нет, всё же это именно “математическая индукция”: http://ru.wikipedia.org/wiki/%D0%9C%D0% … 0%B8%D1%8F
Значит Конан Дойль ошибся.



Офлайн

#9 Фев. 4, 2011 23:43:50

Subideal Ox
От:
Зарегистрирован: 2010-11-23
Сообщения: 65
Репутация: +  0  -
Профиль   Отправить e-mail  

round() в python 2.6

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



Офлайн

#10 Фев. 4, 2011 23:52:09

Isem
От:
Зарегистрирован: 2010-08-27
Сообщения: 447
Репутация: +  7  -
Профиль   Отправить e-mail  

round() в python 2.6

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

Subideal Ox
А парень не сдается! Молодец, гасконец. Так держать!
А что мне еще остается делать?

p.s. вместо споим читаем: спросим
p.s.s. это очень актуально получилось



Отредактировано (Фев. 5, 2011 00:01:27)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version