All streams
Search
Write a publication
Pull to refresh
72
0
Артём Караваев @ArtemKaravaev

Математик-программист

Send message

Есть, попробуйте в decimal64 ввести число, записанное в 13-тиричной системе счисления. В ряде случаев будет возникать бесконечная дробь. Данная проблема есть почти всегда, в книге [1] есть теорема, в которой написано при конвертировании из каких систем счисления с какие не будет такой проблемы.

Оттуда, что при сложении чисел с плавающей запятой в любой системе счисления вы вынуждены смещать одно число относительно другого, когда их экспоненты разные. Результирующая сумма будет занимать больше места, чем позволяет вместить переменная. Значит часть битов будет отброшена. В книге [1] эти вещи, что я описываю в статье, обсуждаются для произвольной абстрактной системы с плавающей запятой, то есть там произвольная система счисления и произвольная, но фиксированная длина мантиссы.

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

Это ещё ладно, я слышал как-то "И ЙЕ ЙЕ ЙЕ — 754" :) Сразу выключил видео, на котором это было.

Благодарю. Совершенно верно, здесь и вычисления полиномов, и просто сумма чисел, и скалярные произведения — всё завязано на этих алгоритмах в том или ином виде (прямо или косвенно).

Это есть в нашем учебном курсе [5]. Я в начале статьи предупредил, что читатель должен быть в курсе этого примера, чтобы мне не пояснять вещи, не относящиеся к теме.

Нет, не так, потому что в вашем примере вы искусственно ограничили условия, о которых в произвольном случае заранее ничего неизвестно. Если есть точные данные относительно слагаемых, то да, можно придумать точные ограничения для промежуточной суммы. А ещё лучше (иногда) будет воспользоваться рациональными числами.

Ну так а я и не оправдываюсь, а благодарю вас за отзыв. Я лишь пояснил, что не посчитал нужным как-то отходить от основной темы. Да, я тоже практик, мне писать просто о теории откровенно скучно, но ведь приходится, потому что без неё не получится дальше описать практику.


Я взял тип данных double просто для единообразия описания, если вы откроете книгу [1], то увидите, что там знания даются с позиции вообще полностью абстрактной системы с произвольным основанием (не только двоичным или десятичным) и произвольной, но фиксированной точностью. Там есть вырвиглазные теоремы и я хочу их как-то обойти. Вот для этого взял и свёл всё к double, понятно, что для float то же самое будет, только битов меньше.


А что касается причин появления разных обёрток, то она намного сложнее, чем вы сейчас пишите. Но я бы не стал дискутировать об этом в комментариях, с вашего позволения :) Это очень длинная тема, и мы уйдём в философию, утомив других читателей.

В следующей статье я собирался показать как разные способы суммирования чисел из массива могут давать погрешности, отличающиеся на несколько порядков. Эти способы, в частности, работают с применением знаний из этой статьи. Если торопитесь изучить эту сферу, то в книге [1] всё есть, я лишь немного от неё отступлю в следующей статье, а по сути расскажу то же самое.

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

Благодарю за отзыв. Но вот в каком непростом положении я нахожусь. Дело в том, что у каждого читателя своя математическая культура, и подстроиться под каждого невозможно. Например, в моём научном коллективе и без слов понятно, когда какой тип данных применять (рациональные числа, с плавающей запятой, с конечной или бесконечной точностью, позиты Джона Густафсона, интервальную арифметику, числа половинной точности или увосьмерённой). У нас все и так знают, что к чему и почему. У других людей может не быть этих знаний, но есть другие знания. Как я могу угадать, какие у них знания? Напишу про точность, мне ответят, что я мог бы этого не писать. Если не напишу, ответят, что надо было написать. Если напишу категорично (никогда не пользуйся), ответят, что иногда можно и даже нужно, если не напишу, то скажут, что надо было написать. Поэтому я написал только по делу. Кто в теме, тому статья полезна будет, кто не в теме, тем я порекомендовал для начала ресурсы [3-5].

Это не будет работать по нескольким причинам. Во-первых, long double уже де-факто отменили (в потоковых обработках), во-вторых, он даёт только 11 дополнительных битов мантиссы, а чтобы сохранить погрешность нужно 52 (для double), в-третьих, возникает ошибка двойного округления… короче, ещё 10 причин я просто не хочу писать, вы уж простите. Мне кажется, вы не вполне поняли проблему.

А, прошу прощения, я не сообразил, что вы именно ему отвечаете :) Опять запутался.


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

Это математическая статья, описываемые явления будут во всех без исключения форматах с плавающей запятой фиксированного размера не зависимо от компилятора, и если формат допускает денормализованные числа. Смысл статьи не в том, чтобы бороться с врождённой проблемой формата и как-то складывать десятичные дроби, а в том, чтобы находить сумму двух чисел без потери точности в уже заданной математической абстракции под названием двоичная арифметика с плавающей запятой. Просто я привязал её к формату IEEE-754, так как он описывает как раз такие числа и всем известен.

Благодарю за замечание, но когда в черновике я так сделал, то увидел, что получается слишком много лишних уточнений. Мне кажется, что по контексту всё должно быть понятно. Особенно если учесть, что я в некоторых местах оставил это уточнение:


Начнём с того, что чисел 0,1 и 0,2 в двоичной арифметике с плавающей запятой...

Благодарю за отзыв. Однако я прошу принять во внимание два обстоятельства. Во-первых, статья в своём названии уже говорит, что складывать мы будем два числа, во-вторых, про сумму чисел из массива сказано, что это будет в другой статье, там я расскажу, как можно уменьшить погрешность (но не убрать её совсем). Мне трудно представить, как читатель может после этого ожидать, что я расскажу об этом именно здесь. Вы говорите о том, что я много повторяюсь, но вы сейчас показали, что всё-таки я повторяюсь мало. Нужно больше.


Забегая вперёд скажу, что посчитать сумму чисел из массива произвольной длины без потери точности можно только одним способом — с помощью арифметики с бесконечной точностью.

Благодарю, Дмитрий. Я приму к сведению ваше предложение.

Благодарю за подборку, я даже как-то прослезился слегка от ностальгии. Демидовича увидел и совсем разрыдался :) Но это было волшебное время...

Благодарю за совет по поводу %a, но в остальном я не могу прокомментировать ваши замечания, потому что из них очевидно, что вы не поняли содержание статьи. Возможно, вы захотите мне возразить, но не стоит, а лучше напишите сразу тем авторам из списка источников, которые более 15 лет уже пытаются решить эту задачу и всё ещё далеки от решения. Возможно, они удивятся, что оказывается всё уже давно решено.


Другая часть ваших замечаний в точности повторяют то, что я и так написал в статьи (например, про то, что мало всяких критических пограничных случаев и что для программиста важнее точность, а не правильность последних битов), поэтому неясно с кем вы спорите. Ясно что не со мной. Даже про числа с бесконечной точностью я говорил (но не называл конкретного пакета). В общем, давайте уважать друг друга. Я внимательно писал статью, а ваша задача — внимательно её прочитать, если намереваетесь дискутировать.

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


  • Бывают пограничные случаи, где ни одной правильной цифры не будет, под удвоением подразумевают возведение точности в квадрат.
  • Бывают условия, при которых квадратичная сходимость скатывается до линейной. И тогда одна итерация, грубо говоря (условно), добавляет только одну цифру.

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Date of birth
Registered
Activity