Форум сайта python.su
М-да… гений - парадоксов друг.
То есть Вы с самого начала знали, что round в 2.6 и 2.7 работают абсолютно одинаково и все дело только в том, как число из внутреннего (абсолютно идентичного) представления преобразуется в строку в разных версиях?
Но зачем тогда нужно было предлагать свой round? И почему Вы спорили с Андреем, который говорил то же самое?
И к чему тогда фраза:
Isem?
Потому что sql сам умеет округлять на выходе
Офлайн
Я кроме питона 3.1 (и других языков) больше ни чем никогда не пользовался. Ну кроме метода дедукции. Да, и методом pickle я тоже никогда не пользовался, потому что это бессмысленно. Зачем мне неизвестный мне формат (это не ошибка), когда я и так знаю, что он записывает (в принципе) ? А моя цитируемая Вами фраза к тому, что мне выдали число, но объяснили это совершенно не так, как это на самом деле происходит, после чего я, естественно, не смог промолчать.
И под моим ником сижу только я.
p.s. А с Андреем я спорил потому, что он меня приравнял, извините, не туда (его первый пост со мной через запятую). Да и сказал он, что я не смог понять что (ну со мной бывает такое иногда) (надеюсь, Андрей на меня зла держать за это не будет).
p.s.s И случай – бог-изобретатель.
Отредактировано (Фев. 5, 2011 01:09:02)
Офлайн
Видимо, это довольно сложная тема, раз все еще остаются вопросы.
Попытаюсь пересказать то, что написано в доках по этому поводу.
Имеем дробь 4.31. В float она хранится в виде <знак>1.<мантисса> * pow(2, <экспонента>)
Знак и экспонента сейчас не важны. Мантисса - дробная часть числа, записанная по основанию два.
Оригинальная запись была “4.31”, дробная часть пишется по основанию 10.
Когда переводим из десятичного основания в двоичное - получаем бесконечную дробь. Примерно как 1/3 в переводе на десятичное основание - тоже бесконечная.
В float мантисса записывается “пока хватает места”, а (бесконечный) остаток выбрасывается.
Если записывать 1/3 с точностью до 3 знаков, получим 0.333. В float 53 (считая со старшей неявной единицей) двоичных разряда. Я не хочу приводить эту длинную простыню ноликов и единичек, достаточно представить что она есть.
Теперь нужно обратно перевести float в строку в десятичном представлении.
Двоичное число стало конечным. Но из-за отсечения не поместившихся бит оно не точно соответствует десятичному числу, из которого конструировалось.
Python 2.6- (и Python 3.0) делали это так: преобразовываем “как есть” и получаем длинный “хвост” - 4.3099999999999996
В Python 3.1 (а после и в Python 2.7) алгоритм поменяли.
Это длинная простыня format_float_short в ./Python/pystrtod.c
Работает она так:
У нас есть мантисса <b1 b2 b3 b4 b5> - на самом деле 52 бита.
Переводим ее в десятичную форму: <d1 d2>. Перевод остановился на b3, например - потому что b4 и b5 не дают десятичного числа.
Последняя десятичная цифра d3 - неполная, потому что входной поток бит закончился раньше, чем мы получили их достаточное количество.
Добавляем в этот поток все возможные комбинации, необходимые для завершения построения d3.
Выбираем из всех возможных d3 такую цифру, чтобы результирующее число имело минимальную запись (чем больше выходит ноликов в конце, тем лучше).
Вуаля, получили минимальное десятичное представление денормализованного двоичного числа.
Внимание, это - не округление в математическом смысле.
Алгоритм подбирает такой остаток, не поместившийся в мантиссу из-за конечного ее размера, чтобы результат можно было записать минимальным количеством цифр.
Точность при этом не теряется - десятичное число “длиннее” в двоичном виде, чем мантисса в float и при этом совпадает с ней на первых 52 битах.
Получилось всё еще довольно длинно и запутанно - но этот вопрос вообще нелегко объясняется “на пальцах”.
Вот документ, с которого всё начиналось: http://www.cs.indiana.edu/~burger/FP-Printing-PLDI96.pdf
Довольно много математики.
Офлайн
IsemНапример, СУБД ZODB построена на базе pickle.
Да, и методом pickle я тоже никогда не пользовался, потому что это бессмысленно.
IsemДействительно, зачем вообще такие форматы, лучше такой формат, в котором никто не знает, что он записывает =)
Зачем мне неизвестный мне формат (это не ошибка), когда я и так знаю, что он записывает (в принципе)?
Офлайн
Андрей СветловКак правило.
Довольно много математики.
Офлайн
regallНу это передергивание. Пусть даже и со смайликом. :)
Действительно, зачем вообще такие форматы, лучше такой формат, в котором никто не знает, что он записывает
Офлайн
Эм… Может тему из новичков в профессионалы перенесём? :)))))
Офлайн