|
Python, вопросы |
|
|
|
Feb 25 2013, 07:13
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Привет! Долго мне питон не нравился, потом таки постепенно начал вникать, дух противоречия спадает. Решил отбросить разное лишнее, калькулятор в частности, и пользоваться питоноконсолью. Но сегодня с утра я в шоке: Код Python 2.7.3 (default, Sep 26 2012, 21:53:58) [GCC 4.7.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> 40.0-37.96 2.039999999999999 >>> Что бы это значило?  -- Граница глюка >>> 40-31.2 8.8 >>> 40-32.2 7.799999999999997 Причем, в выражениях - то же самое. Это чтож оно насчитает в итоге?! Вести с полей. Если пишешь print 40-37.96 то выводит 2.04 Нет никакого желания продолжать дальше. На использование в кач-ве калькулятора можно забить. И хорошо, что из книжек 80-х годов осталась масса макулатуры по бейсику, там всегда были контрольные примеры. Проверим, что эта гадость в компании с numPy насчитает, хотя бы с матрицами. Ух, как я зол!
Сообщение отредактировал _Pasha - Feb 25 2013, 07:14
|
|
|
|
|
Feb 25 2013, 07:17
|
Частый гость
 
Группа: Свой
Сообщений: 97
Регистрация: 6-02-09
Пользователь №: 44 487

|
это уже прочитал? Вообще-то питон честно следует ieee-шному стандарту на числа с плавающей точкой и показывает их так, как видит машина. И бейсик и фортран (даже матлаб) вам посчитают точно то же самое, только вывод на экран там -- как бы это поточнее сказать -- более "умный".
Сообщение отредактировал demidrol - Feb 25 2013, 07:23
|
|
|
|
|
Feb 25 2013, 07:43
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(demidrol @ Feb 25 2013, 10:17)  И бейсик и фортран (даже матлаб) вам посчитают точно то же самое, только вывод на экран там -- как бы это поточнее сказать -- более "умный". Где-то должно что-то задаваться для подобного представления, чует мое сердце. Но это все цветочки. Берем онлайн конвертер ieee754 в зубы и курим Код исходное после преобр. к double 40.0 40.0 30.2 30.200000762939453 31.2 31.200000762939453 32.2 32.20000076293945 Я перестаю понимать. При вычитании чушь начинается как только экспоненты стали равны. А у 40 и 32.2 экспонента == 5 До того, по законам жанра, должны выравниваться порядки и только после вычитаться мантиссы. И в этом случае все нормально, хотя "мусор" в вычитаемом тот же. А представления меняются. Чушь? Чушь собачья!
Сообщение отредактировал _Pasha - Feb 25 2013, 07:45
|
|
|
|
|
Feb 25 2013, 10:19
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Код Python 2.7.2 (default, Jun 12 2011, 15:08:59) [MSC v.1500 32 bit (Intel)] on win 32 Type "help", "copyright", "credits" or "license" for more information. >>> 30.2+31.3 61.5 >>> 32.2+31.25 63.45 >>> Венда, версия пытона на 1 младше, чем Код >>> 40-37.96 2.039999999999999 >>> 40-32.2 7.799999999999997 >>>  А вот так: Код >>> a = 40-32.2 >>> print a 7.8 >>>
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Feb 25 2013, 10:50
|

инженер
   
Группа: Свой
Сообщений: 520
Регистрация: 19-09-05
Из: Самара
Пользователь №: 8 701

|
Ага, непонятно почему print с его стандартными модификаторами e, f, g и т.п. игнорируется? Вообще то, если уж задумываться о точности и возможностях Питона с его динамическими типами, то наверно стоит познакомиться также с такими пакетами Python library for arbitrary-precision floating-point arithmeticЦитата Mpmath is a pure-Python library for multiprecision floating-point arithmetic. It provides an extensive set of transcendental functions, unlimited exponent sizes, complex numbers, interval arithmetic, numerical integration and differentiation, root-finding, linear algebra, and much more. Almost any calculation can be performed just as well at 10-digit or 1000-digit precision, and in many cases mpmath implements asymptotically fast algorithms that scale well for extremely high precision work. Mpmath internally uses Python's builtin long integers by default, but automatically switches to GMP/MPIR for much faster high-precision arithmetic if gmpy is installed
|
|
|
|
|
Feb 25 2013, 11:14
|
Знающий
   
Группа: Участник
Сообщений: 781
Регистрация: 3-08-09
Пользователь №: 51 730

|
Цитата _Pasha: Что бы это значило? Это означает, что множество чисел типа double не содержит числа 2.04 Цитата Если пишешь print 40-37.96 то выводит 2.04 print выполняет округление. Цитата Ух, как я зол! Пользуйтесь прогами позволяющими оперировать с числами произвольной точности. Например, pari/gp, J... Хотя, для подавляющего большинства вычислений точности даблов хватает. Не очень понимаю, что именно вас не устраивает.
|
|
|
|
|
Feb 25 2013, 11:26
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(Виктория @ Feb 25 2013, 12:43)  То есть исходный вопрос заключается все-таки "Как правильно вывести на печать?" Все-таки вопрос такой, точнее, я бы сделал так, чтобы для операндов в выражении, состоящем исключительно из операций сложения/вычитания, учитывалась точность входных операндов и результат округлялся до той точности, которая максимальная. Насчет тотальной применимости - сомневаюсь, можно сломать арифметику, но в консольном режиме это просто должно быть. Цитата(Виктория @ Feb 25 2013, 13:50)  Вообще то, если уж задумываться о точности и возможностях Питона с его динамическими типами, то наверно стоит познакомиться также с такими пакетами Ага. Спасибо, у меня его еще нет. Цитата(MrYuran @ Feb 25 2013, 13:19)  Венда, версия пытона на 1 младше, чем Невероятно, но Код Python 2.7.3 (default, Sep 26 2012, 21:53:58) [GCC 4.7.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> 32.2+31.25 63.45 >>> 30.2+31.3 61.5 >>> 37.96+2.04 40.0 >>> Цитата(thermit @ Feb 25 2013, 14:14)  Это означает, что множество чисел типа double не содержит числа 2.04 Судя по листингу выше, это ничего не означает
Сообщение отредактировал _Pasha - Feb 25 2013, 11:38
|
|
|
|
|
Feb 25 2013, 12:00
|
Знающий
   
Группа: Участник
Сообщений: 781
Регистрация: 3-08-09
Пользователь №: 51 730

|
Цитата Судя по листингу выше, это ничего не означает Означает. Даже не сомневайтесь. А вот листинг действительно ничего не означает, ибо Код >> 37.96+2.039999999999999
ans =
40 >> 37.96+2.039999999999998
ans =
40 >> 37.96+2.039999999999997
ans =
40 >> 37.96+2.04
ans =
40 Успехов в поиске несуществующих глюков.
|
|
|
|
|
Feb 25 2013, 12:18
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(thermit @ Feb 25 2013, 15:00)  Успехов в поиске несуществующих глюков. Спасибо, ужЕ нашел Еще раз, механика скорбного дела. 37.96+2.04 Выровняли порядки и сложили. Ошибка представления ушла от сдвигов мантиссы 2.04 вправо. -- Вычли из 40 37.96 появилась ошибка представления. Вопросов нет. -- Вычли из 40 31.2 после приведения порядков ошибка представления ушла? А нормализация с непременным сдвигом влево? -- Вопрос: почему нельзя сразу округлить результат до числа, представленного наибольшей точностью? Если эти точности заданы явно? Кому это полезно?
Сообщение отредактировал _Pasha - Feb 25 2013, 12:22
|
|
|
|
|
Feb 25 2013, 13:25
|
Знающий
   
Группа: Участник
Сообщений: 781
Регистрация: 3-08-09
Пользователь №: 51 730

|
Цитата _Pasha: Вычли из 40 31.2 после приведения порядков ошибка представления ушла? Куда кто ушел? 31.2 уже не представимо. Мантисса не позволяет. Ближайшее 31.199999999999999.
|
|
|
|
|
Feb 25 2013, 15:02
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(thermit @ Feb 25 2013, 16:25)  Куда кто ушел? 31.2 уже не представимо. Мантисса не позволяет. Ближайшее 31.199999999999999. Вот и именно. 40.0 = 1.25*2^5 31.2 = 1.9500000476837158 * 2^4=0.975000023841858*2^5 (казалось бы, здесь она уменьшается, эта ошибка) 40.0-31.2 = 0.274999976158142*2^5= 8.79999923706054-- А пишет 8.8 Т.е. в зависимости от того, как там дела на Марсе, он то "хочет" округлить то "не хочет" -- Для более придирчивого взгляда, обобщу: если мы из представимого множеством double числа вычтем непредставимое, то в результате обязательно получим непредставимое, а в консоли это не так.
Сообщение отредактировал _Pasha - Feb 25 2013, 15:41
|
|
|
|
|
Feb 25 2013, 17:46
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(Виктория @ Feb 25 2013, 20:12)  Может сервис локализации тут мельтешит?( Параметры категории LC_NUMERIC, какое правильное значение grouping для Ваших примеров - никак не соображу, в Excel всё это выглядит как-то прозрачнее). OK. Смотрим, ессно, дефолтный локаль, какой эст Код >>> import locale >>> locale.localeconv() {'mon_decimal_point': '', 'int_frac_digits': 127, 'p_sep_by_space': 127, 'frac_digits': 127, 'thousands_sep': '', 'n_sign_posn': 127, 'decimal_point': '.', 'int_curr_symbol': '', 'n_cs_precedes': 127, 'p_sign_posn': 127, 'mon_thousands_sep': '', 'negative_sign': '', 'currency_symbol': '', 'n_sep_by_space': 127, 'mon_grouping': [], 'p_cs_precedes': 127, 'positive_sign': '', 'grouping': []} >>> Врядли оно тутта при чём. Это чистая проблема конверсии double -> string До системы уравнений пока сегодня не добрался  на предмет чреватости ошибки, но это тоже врядли. Не может же весь мир дураками быть, в конце концов! -- Покурю-ка я исходники 2.7.3 Себе полезно, - людЯм интересно  Тем более, документировано - ну просто красота!
Сообщение отредактировал _Pasha - Feb 25 2013, 18:07
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|