Перейти к содержанию
    

Привет!

Долго мне питон не нравился, потом таки постепенно начал вникать, дух противоречия спадает.

Решил отбросить разное лишнее, калькулятор в частности, и пользоваться питоноконсолью.

Но сегодня с утра я в шоке:

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
>>>

Что бы это значило? :crying:

--

Граница глюка

>>> 40-31.2

8.8

>>> 40-32.2

7.799999999999997

Причем, в выражениях - то же самое. Это чтож оно насчитает в итоге?!

 

Вести с полей.

Если пишешь print 40-37.96 то выводит 2.04

Нет никакого желания продолжать дальше. На использование в кач-ве калькулятора можно забить. И хорошо, что из книжек 80-х годов осталась масса макулатуры по бейсику, там всегда были контрольные примеры. Проверим, что эта гадость в компании с numPy насчитает, хотя бы с матрицами. Ух, как я зол!

Изменено пользователем _Pasha

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

это уже прочитал? Вообще-то питон честно следует ieee-шному стандарту на числа с плавающей точкой и показывает их так, как видит машина.

 

И бейсик и фортран (даже матлаб) вам посчитают точно то же самое, только вывод на экран там -- как бы это поточнее сказать -- более "умный".

Изменено пользователем demidrol

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И бейсик и фортран (даже матлаб) вам посчитают точно то же самое, только вывод на экран там -- как бы это поточнее сказать -- более "умный".

Где-то должно что-то задаваться для подобного представления, чует мое сердце.

Но это все цветочки. Берем онлайн конвертер ieee754 в зубы и курим

исходное        после преобр. к double
40.0                40.0
30.2                30.200000762939453
31.2                31.200000762939453
32.2                32.20000076293945

Я перестаю понимать. При вычитании чушь начинается как только экспоненты стали равны.

А у 40 и 32.2 экспонента == 5

До того, по законам жанра, должны выравниваться порядки и только после вычитаться мантиссы. И в этом случае все нормально, хотя "мусор" в вычитаемом тот же. А представления меняются. Чушь? Чушь собачья!

Изменено пользователем _Pasha

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

То есть исходный вопрос заключается все-таки "Как правильно вывести на печать?"

Сегодня праздник "чистых" программистов?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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
>>>

 

:smile3046:

 

А вот так:

>>> a = 40-32.2
>>> print a
7.8
>>>

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ага, непонятно почему 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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

_Pasha:

Что бы это значило?

 

Это означает, что множество чисел типа double не содержит числа 2.04

 

Если пишешь print 40-37.96 то выводит 2.04

 

print выполняет округление.

 

Ух, как я зол!

 

Пользуйтесь прогами позволяющими оперировать с числами произвольной точности.

Например, pari/gp, J...

Хотя, для подавляющего большинства вычислений точности даблов хватает. Не очень понимаю, что именно вас не устраивает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

То есть исходный вопрос заключается все-таки "Как правильно вывести на печать?"

Все-таки вопрос такой, точнее, я бы сделал так, чтобы для операндов в выражении, состоящем исключительно из операций сложения/вычитания, учитывалась точность входных операндов и результат округлялся до той точности, которая максимальная. Насчет тотальной применимости - сомневаюсь, можно сломать арифметику, но в консольном режиме это просто должно быть.

 

Вообще то, если уж задумываться о точности и возможностях Питона с его динамическими типами, то наверно стоит познакомиться также с такими пакетами

Ага. Спасибо, у меня его еще нет.

 

Венда, версия пытона на 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
>>>

 

Это означает, что множество чисел типа double не содержит числа 2.04

Судя по листингу выше, это ничего не означает :)

Изменено пользователем _Pasha

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Судя по листингу выше, это ничего не означает

 

Означает. Даже не сомневайтесь.

А вот листинг действительно ничего не означает, ибо

 

>> 37.96+2.039999999999999

ans =

    40
>> 37.96+2.039999999999998

ans =

    40
>> 37.96+2.039999999999997

ans =

    40
>> 37.96+2.04

ans =

    40

 

Успехов в поиске несуществующих глюков.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Успехов в поиске несуществующих глюков.

Спасибо, ужЕ нашел :biggrin:

Еще раз, механика скорбного дела.

37.96+2.04 Выровняли порядки и сложили. Ошибка представления ушла от сдвигов мантиссы 2.04 вправо.

--

Вычли из 40 37.96 появилась ошибка представления. Вопросов нет.

--

Вычли из 40 31.2 после приведения порядков ошибка представления ушла? А нормализация с непременным сдвигом влево?

--

Вопрос: почему нельзя сразу округлить результат до числа, представленного наибольшей точностью? Если эти точности заданы явно? Кому это полезно?

Изменено пользователем _Pasha

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

_Pasha:

Вычли из 40 31.2 после приведения порядков ошибка представления ушла?

 

Куда кто ушел? 31.2 уже не представимо. Мантисса не позволяет. Ближайшее 31.199999999999999.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Гм, ради интереса у себя все проверил... Тоже самое) Как быть-то?

Python 3.2.3 (default, Apr 11 2012, 07:15:24) [MSC v.1500 32 bit (Intel)] on
32
Type "help", "copyright", "credits" or "license" for more information.
>>> 40.0-37.96
2.039999999999999

>>> print (40.0 - 37.96)
2.039999999999999
>>>

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Куда кто ушел? 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 :cranky:

Т.е. в зависимости от того, как там дела на Марсе, он то "хочет" округлить то "не хочет"

--

Для более придирчивого взгляда, обобщу: если мы из представимого множеством double числа вычтем непредставимое, то в результате обязательно получим непредставимое, а в консоли это не так.

Изменено пользователем _Pasha

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Т.е. в зависимости от того, как там дела на Марсе, он то "хочет" округлить то "не хочет"

 

Может сервис локализации тут мельтешит?( Параметры категории LC_NUMERIC, какое правильное значение grouping для Ваших примеров - никак не соображу, в Excel всё это выглядит как-то прозрачнее).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может сервис локализации тут мельтешит?( Параметры категории 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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...