Как стать автором
Обновить

Комментарии 158

Ещё бы нативную поддержку вычислений в СДДФ на FPU… выглядит привлекательно. По крайней мере при правильном выборе разбиения на мантиссу и показатель увеличивается диапазон представимых чисел вместе с фактическим увеличением точности (мантисса длиннее)! Но есть вопрос — а что если взять вместо десяти — шестнадцать? Т.е. формула S*M2*10^e превращается в S*M2*16^e, получим примерно то же самое, что с десятью, увеличится точность (на 0-3 двоичных разряда) и увеличится размер представимых чисел. Однако в одном наборе данных нельзя увеличить сразу все показатели. Где подвох?
увеличивается диапазон представимых чисел вместе с фактическим увеличением точности (мантисса длиннее)!

Точность двоичная и точность десятичная — разные вещи. Попробуйте представить десятичное число 0.1в двоичном виде с точностью до одной значащей десятичной цифры. Сколько бы двоичных разрядов вы не брали для представления числа 0.1, вы не сможете его точно представить в этом коде. Как впрочем и в 16-ричном коде. Это связано с тем, что системы счисления с базой b=2^q, где q=1,2,3… — степень двойки, не соизмеримы с системами счисления c базой b=10^n (n=1,2..). В 16-разрядном же СДДФ число 0.1= 1100100*10^-3=100*10^-3. Т.е. число представлено точно.
Всё же, например, число 1+1/1048576 можно точно представить в двоичном виде, но не получится точно представить в десятичном (точнее, понадобится мантисса в 20 десятичных цифр). Получается, что подвох в том, что уменьшается плотность точно представимых чисел — тогда как именно?

И все же, а что насчет 16 в качестве основания степени?
Если не ограничивать разрядность машинного слова ( в пределах разумного), то любое двоичное вещественное число можно однозначно представить в десятичном виде. Наоборот это не работает. Только представимые десятичные числа можно представить в двоичном виде и в шестьнадцатиричном тоже. Мы привыкли оперировать десятичными числами. Даже стандарт IEEE754 для двоичных чисел с плавающей точкой все основные характеристики чисел приводит в десятичном виде. Практически все тестовые программы, в конечном счете, сравнивают результаты работы с десятичными числами. Поэтому логично оперировать с десятичными числами и получать результат такой же точности, как при вычислениях вручную. Понимая это, многие производители реализуют аппаратную поддержку десятичной арифметики на аппаратном уровне, используя BCD. Правда, ценой значительных затарат.
Если не ограничивать разрядность машинного слова ( в пределах разумного), то любое двоичное вещественное число можно однозначно представить в десятичном виде. Наоборот это не работает.

Что-то меня это малость удивляет. "Здравый смысл" говорит нам, что если не ограничивать разрядность, не должно быть разницы, из какого основания системы счисления в какую вы переводите.

«В пределах разумного», насколько я понимаю, означает конечную разрядность. А в этом случае уже работает, да, то, что 0.1 в десятичной равно 0.00011001100110011… = 0.0(0011) в двоичной — бесконечная периодическая дробь. В этом смысле он вполне прав.
А вот дальше вопрос, какой вывод делать из этого факта. Как для меня, то, что мы можем представить десятичное число двоичным с любой необходимой точностью (например, нужно 30 десятичных разрядов — берём 100 двоичных бит), достаточно для практики. А вот для ТС почему-то этого недостаточно.
Дело в цене вопроса. В формате сингл, при вычислениях за верные цифры ответа принимаются только 3..5 десятичных разрядов, при том, что при конвертации в двоичный код мы получаем 7 верных цифр. В дабле, вместо 15 верных цифр ограничиваются 7..8 десяиичными цифрами. Причем округление, производится в компиляторе. В СДДФ мы получаем при всех операциях ответ с точностью до 7 значащих цифр. Без хвостов.
Дело в цене вопроса [...] В СДДФ мы получаем при всех операциях ответ с точностью до 7 значащих цифр.

И какова цена вопроса?

Она определена в двух последних топиках.

Я не знаю, что такое топик, и откуда считать "два последних", поэтому можно мне все-таки услышать про цену вопроса?

Топик, от слова top — верх, вверху статьи всегда название, то есть это заголовок статьи. В длинном обсуждении на какую-то тематику, тема меняется без разрыва самого процесса переписки, поэтому этапы обсуждения разделяют по смыслу на топики, отсюда и отдельное слово с уклоном в комментарии, а не сами статьи. Следовательно, автор имел ввиду тематику комментариев к двум последним статьям.
этапы обсуждения разделяют по смыслу на топики

Если вы наблюдали за серией моих статей на хабре. А вы таки наблюдали, мы с вами уже однажды дискутировали. То обратили наверно внимание на то, что тема в них не менялась. Хотя вы, вероятно, правы, слово выбрано не совсем корректно.
И судя по всему, автор привык вести обсуждения без всяких статей, поэтому ошибочно свои статьи именует топиками.
автор привык вести обсуждения без всяких статей, поэтому ошибочно свои статьи именует топиками.
> В формате сингл, при вычислениях за верные цифры ответа принимаются только 3..5 десятичных разрядов

Простите, кем это они так принимаются?
В single гарантированно 6 верных десятичных цифр на всех диапазонах, и 7 на большинстве.

Причём также доказано, что именно за счёт того, что 2 < 10 < 16, двоичная арифметика имеет меньшую погрешность при каждом округлении результата для его «утаптывания» в выходной single/double/etc., чем десятичная, и особенно, чем шестнадцатиричная (почему собственно base16 проиграло спор за стандарт плавучки).

> В дабле, вместо 15 верных цифр ограничиваются 7..8 десяиичными цифрами.

А это вообще фантастика какая-то — в double, аналогично, 15 гарантированных десятичных цифр (и 16-я чуть больше, чем на половине диапазона).

> Причем округление, производится в компиляторе.

WAT? Где вы это нашли? Что за компилятор такой безумный?

> В СДДФ мы получаем при всех операциях ответ с точностью до 7 значащих цифр. Без хвостов.

Вы видите «хвосты» только потому, что оцениваете точность двоичной арифметики в понятиях десятичной. На самом деле всё наоборот: двоичная точнее, просто у неё другая сетка значений.
И то, что шаг сетки значений у неё равномернее — при смене порядка шаг меняется не в 10 раз, а только в 2 — тоже существенно помогает точности результата.
Давайте разделим точность представления и точность вычисления. В формате сингл можно представить числа с точностью до 7 верных знаков, в дабл — с точностью 15,16 верных знаков. Но когда вы будете производить арифметические вычисления, количество верных знаков в ответе могут катастрофически быстро сокращаться (См. мой предыдущий топик) И виной тому именно те хвосты, которые мы не видим.
Что касается точности. Какая абсолютная и относительная погрешность у точного числа или у точных вычислений? Вычисления на калькуляторе, которые реализованы в BCD, какую имеют точность? И какой двоичный операционный регистр нужно иметь, чтобы обеспечить точность вычислений до, скажем 7 значащих цифр. Причем так, чтобы на очередной итерации хвосты не оказали на результат разрушающего действия?
> Но когда вы будете производить арифметические вычисления, количество верных знаков в ответе могут катастрофически быстро сокращаться (См. мой предыдущий топик) И виной тому именно те хвосты, которые мы не видим.

Нет, в вычислениях в двоичной арифметике количество верных знаков сокращается значительно медленнее, чем в десятичной.
Проверять это надо не на паре операций, а на длинных вычислениях на действительно много операций (сотни, тысячи, миллионы).

И только на проблемах обратной конверсии в вывод в десятичном формате можно обратно потерять пол-цифры. Потому эту конверсию надо откладывать как можно дольше. А лучше вообще не делать, если не надо — если нужен текстовый формат, %a в C стандартизован ещё в 1999-м:

> Что касается точности. Какая абсолютная и относительная погрешность у точного числа или у точных вычислений?

Видите ли, вы пытаетесь получить ответ в один абзац там, где люди годами проводили измерения и писали целые книги по обоснованию точности вычислений.
Я сейчас не готов послать к конкретным книгам и статьям. Они публиковались под эгидой ACM, IEEE, других аналогично авторитетных организаций. В популярной литературе эта тема очень слабо освещена. Поэтому я предлагаю пока что просто принять на слово как первичные данные, что двоичная плавучка оказалась выгоднее в плане как скорости, так и качества результата, для того, для чего она в первую очередь задумывалась — я это для краткости называю словом «матфизика».
Нет, в вычислениях в двоичной арифметике количество верных знаков сокращается значительно медленнее, чем в десятичной.

Нам дали некое 24-х разрядное двоичное число: 1.00011111011111001110111 и попросили его отнять от двоичного числа 1.00011111001110110110010. Результат должен быть представлен тоже 24-х разрядным нормализованным числом. В результате получим число 1.0000011000101*2^-10. В приведенных вычислениях все числа состоят только из верных двоичных цифр, т.к. округлений мы не производили.
А теперь надо найти разность двух десятичных чисел 1.123-1.122 Очевидно, она будет равна 0.001 Здесь все десятичные числа содержат только верные цифры.
А теперь вычислим разность этих десятичных чисел, используя двоичную арифметику.
1.123= 1.00011111011111001110111
1.122=1.00011111001110110110010
1.00011111011111001110111-1.00011111001110110110010= 0.00000000010000011000101=1.0000011000101*2^-10= 0.00100004673004150390625
Мы видим, что в результате ulp=0.4673004150390625. Это и есть неверные цифры, которые появились в конечном результате.
Если вы обратите внимание, двоичные эквиваленты наших десятичных чисел 1.123 и 1.122 в последнем примере совпадают с двоичными числами из первого примера.
Таким образом, в первом примере все двоичные числа были верными, а во втором примере двоичные эквиваленты наших десятичных чисел оказались приблизительными числами, содержащими неверные цифры. В рамках двоичной арифметики от них не избавишься и при дальнейших вычислениях они будут влиять на результаты.

> А теперь надо найти разность двух десятичных чисел 1.123-1.122

Как только вы вступили на эту тропу, вы имеете дело не с проблемами десятичной или двоичной арифметики самой по себе, а с эффектами, которые происходят от переквантования на другую сетку значений. И пока вы вместо рассмотрения погрешности конкретной арифметики самой по себе будете вменять им эффекты этого переквантования — вы ничего полезного не поймёте.

> двоичные эквиваленты наших десятичных чисел оказались приблизительными числами, содержащими неверные цифры

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

Это не я вступил, а те, кто двоичной арифметикой решают десятичные примеры, пусть и с огромным количеством членов. Очередной раз повторюсь. Законы арифметики действуют на двоичные числа в рамках двоичной арифметики. Законы десятичной арифметики действуют в рамках десятичной арифметики. Проблемы начинаются тогда, когда десятичную арифметику решают инструментарием двоичной.
Что значит фраза «с эффектами, которые происходят от переквантования на другую сетку значений» я не понял.
В ваших работах я объяснения не нашел. Поясните.
Но на практике это никого не интересует, кроме тех, кому зачем-то нужна формальная корректность именно одиночных операций в десятичном виде.

Длинные вычисления складываются из одиночных операций. И если одиночные операции ошибочны, ошибочен и результат.
Вы в своих рассуждениях все время упоминаете длинные расчеты. Видимо, имея ввиду, что в результате статистической независимости ошибок они взаимно компенсируются. Но, это не верное утверждение. В своей статье «Рекуррентные формулы для расчета ошибок итерационного суммирования двоичных чисел ограниченной длины» я показал, что для таких чисел основная ошибка формируется не от ошибок преобразования, а от ошибок округления. Причем ошибки округления только складываются.
И в заключении. А вы пользуетесь в матфизике калькулятором, или это для вас атавизм? Почему вы так не любите точных вычислений?
> Проблемы начинаются тогда, когда десятичную арифметику решают инструментарием двоичной.

Проблемы начинаются, когда требования точности сводят к формулировкам в виде точных десятичных цифр.

> Причем ошибки округления только складываются.

Не только и не складываются. С этой теорией вы тоже не очень знакомы.

> И в заключении. А вы пользуетесь в матфизике калькулятором, или это для вас атавизм? Почему вы так не любите точных вычислений?

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


В нашей дискусси столько раз говорится о точности. Но вы это понятие никак не сформулировали, ссылаясь на то, что столпы еще не достаточно сами разобрались. Я определение точности прводил выше. Хотелось бы понять, что вы понимаете под этим словом?
Не только и не складываются. С этой теорией вы тоже не очень знакомы.

Смотря как округлять.
Когда я привожу свои доводы, я либо даю ссылки на источники, либо привожу примеры. Вы же меня постоянно обвиняете, что я чего-то не знаю и рассказываете о столпах. Так покажите, где я ошибаюсь, дайте ссылки, приведите примеры. И не пример, типа, в decimal это будет так. decimal такое же двоичное число, только длинное.
Я люблю точные вычисления больше, чем вы, судя по этой дискуссии.
Калькулятором — да, не пользуюсь. Компьютер удобнее и результаты не хуже.

А с чем вы сравниваете результаты? Судя по тому, что «результаты не хуже», все таки с ненавистным калькулятором.
двоичная арифметика имеет меньшую погрешность при каждом округлении результата для его «утаптывания» в выходной single/double/etc., чем десятичная, и особенно, чем шестнадцатиричная (почему собственно base16 проиграло спор за стандарт плавучки).

Ага, вот и ответ нашелся. Все-таки не зря говорят, что в споре рождается истина — но надо её успеть поймать, пока не ушла, за подол. ;)

> Ага, вот и ответ нашелся. Все-таки не зря говорят, что в споре рождается истина

Она не рождается, она озвучивается. Родилась-то она заметно раньше — то, что я тут рассказываю, хорошо известно специалистам… но они тоже могут не часто это вспоминать — например, ссылки были у того же Кнута, но в его объёме их элементарно тупо потерять. А в форме спора, да, оно может всплыть и к тому же быть сформулировано ещё десятком способов, так что поймут все, кто даже читает вскользь.
Хоть это и не касается темы моей статьи, не могу, в очередной раз, не возразить вам.
Осмелюсь замахнуться, страшно сказать, на самого Дэвида Голдберга, и ужаснее всего, на его хрестоматийную статью "What Every Computer Scientist Should Know About Floating-Point Arithmetic". В котрой в частности в разделе Base говорится: Consider the computation of 15/8. When b = 2, 15 is represented as 1.111 × 2^3, and 15/8 as 1.111 × 2^0. So 15/8 is exact. However, when = 16, 15 is represented as F × 16^0, where F is the hexadecimal digit for 15. But 15/8 is represented as 1 × 16^0, which has only one bit correct. In general, base 16 can lose up to 3 bits, so that a precision of p hexadecimal digits can have an effective precision as low as 4p — 3 rather than 4p binary bits. Since large values of b have these problems, why did IBM choose b= 16 for its system/370? Only IBM knows for sure..."
Только не давите на меня своими столпами. Найдете ошибку сообщите.
Но Голдберг здесь делает ту же ошибку, что и вы. Если оперировать не форматами а машинным словом, то для двоичных чисел выбрано двоичное слово: 4-мантисса, 2-экспонента итого 4+2=6 разрядов. А для 16-ричного представления он почему-то оставляет только 4 разряда. На самом деле, если 15=F (4 разряда), 8=8 (1 разряд) то для десятичных чисел 15/8=1.875, что в 16-ричном и двоичном виде равно F/8= 1.E*16^0=1.111. Данное число представляется также как и двоичное, 6-ю разрядным словом. Только 1 разряд — экспонента, 5 разрядов мантисса. В нашем случае даже 4 разряда, поскольку E в дроби, а для F потребуется еще один. Более того, если в двоичном виде число 1.111*2^3=15, то для 16-тиричных чисел с 6-разрядным словом максимальное число будет 1.F*16^1=31. Ну и где здесь потеря точности?
В обсуждаемой статье рассматривается реализация десятичной арифметики инструментарием двоичной. Преимущества и недостатки той или иной системы не есть предмет обсуждения расматриваемой статьи. Что касается десятичной арифметики, наиболее подробно можно почитать в статье одного из основных разработчиков десятичной арифметики для станадрта IEEE754-2008 Майка Коулишева (Mike Cowlishaw) General Decimal Arithmetic.
Меня удивляет то, что Вас это удивляет. Не любую дробь можно представить в виде конечной двоичной или десятичной дроби.
Так вот, любую конечную двоичную дробь можно представить в виде конечной деятичной дроби, потому что 10 делится на 2, значит, для любой степени двойки, найдётся такая степень десятки, которая содержит эту степень двойки как множитель.
Обратное неверно. 1/5 не представима в виде конечной двоичной дроби, потому что не существует такой степени двойки, которая бы делилась на 5.
Не любую дробь можно представить в виде конечной двоичной или десятичной дроби.

А я вроде бы и не собирался представлять что-то в виде дроби.

Вы, не иначе, меня троллите.
двоичное вещественное

Ага. Не в виде дроби.

Нет, не троллю, совершенно серьезно. Требование было на двоичную запись, а не на запись в виде дроби.

В таких терминах, предлагаемая автором система кодирования — тоже двоичная.

Вполне возможно.

Конечно двоичная. Только в СДДФ двоичным кодом кодируется вещественное десятичное число, или десятичное число с плавающей точкой.
16-ричные числа с плавающей точкой уже были: в IBM-360/370. Разница между двоичным и 16-ричным представлениями только в том, что изменение порядка на 1 в двоичном числе сдвигает положение точки на 1 бит, а в 16-ричном — на 4 бита.
Попробуйте представить десятичное число 0.1в двоичном виде с точностью до одной значащей десятичной цифры.

0.1 = 10^-1 = 1e-1. И 1, и -1 прекрасно представимы в двоичном виде.

Правильно. Но представте это число в формате двоичного числа с плавающей точкой и получите бесконечное двоичное число.
Но представте это число в формате двоичного числа с плавающей точкой и получите бесконечное двоичное число.

Вы, наверное, имеете в виду какой-то конкретный формат двоичного числа с плавающей точкой?

Нет, я имею ввиду принципиальную невозможность представить это число в двоичном виде.
lair не врет, допустим я формат такой сам специфицировал (и получил за него премию от IEEE):
8 бит — числитель
8 бит — знаменатель
никакой экспоненты.
пишут 1 в num, 1010 в denum, вуаля, я представил ТОЧНО 0.1 в двоичном коде. Что не так?
И такое представление имеет место быть (См. здесь)

Эм, я вам только что показал, что это число представимо в двоичном виде.

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

Мы обсуждаем "принципиальную невозможность представить это число [0.1] в двоичном виде".

Зачем?

Затем, что вы приводите это как аргумент.

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

Вне зависимости от контекста, этот аргумент неверен. Значит, использовать его для доказательства чего-либо в контексте нельзя.

Согласен. Не буду.
Вы хитрите. У вас основание экспоненты десятка, а не двойка. Т.е. система не двоичная.

Представление — двоичное. Все числа из записи 1*(10^-1) можно записать в двоичном виде, следовательно, вся эта запись прекрасно представляется в двоичном виде.

Софистика детектед. Если произвольно трактовать термин «двоичное представление», то представить в нём можно всё что угодно.
Можно вообще выдумать систему кодирования, в которой можно будет точно представлять числа, представимые в радикалах.

Ну а как вы предлагаете трактовать термин, определение которому не было введено в рамках дискуссии?

Вообще говоря, вся информация в компьютере кодируется двоичным кодом. Десятичные числа кодируются (представляются) целыми числами, с фиксированной точкой, с плавающей запятой, двоичными тетрадами и проч. Вопрос в том, как расшифровать код, записанный в машинном слове и на сколько представление числа этим кодом «удобно» для дальнейшего использования, каким требованиям оно должно удовлетворять. В конце концов, двоичным кодом можно просто записать слова «ноль целых, одна десятая». И это точное представление числа 0.1 Другое дело, складывать числа в таком представлении неудобно.
> Попробуйте представить десятичное число 0.1в двоичном виде с точностью до одной значащей десятичной цифры. Сколько бы двоичных разрядов вы не брали для представления числа 0.1, вы не сможете его точно представить в этом коде.

Так «точно» или «с точностью до одной значащей десятичной цифры»?

Если первое, то, действительно, бесконечная периодическая дробь в двоичной системе — но что мешает её обрезать на нужном месте?

Если второе, то достаточно того, что 0.001₂ == 0.125 ближе к 0.1, чем к 0.2, затем 0.0011₂ == 0.1875 ближе к 0.2, чем к чему-то ещё, 0.0101₂ == 0.3125 к 0.3… итого, мы для любого значения с шагом 0.1 имеем двоичное число с 4 разрядами после запятой, которое ближе к нему, чем к другому соседнему значению.
Я не буду говорить о затратах на реализацию этого алгоритма. Сложите два числа 0.1+0.1, каждое из которых представлено 4 двоичными разрядами. 0.1= 0.0010. 0.0010+0.0010=0.0100=0.25 Вас такой ответ устроит?
В СДДФ, с 4 разрядами под мантиссу и 2 разрядами под экспоненту это будет:
0.1=10*10^-2= 1010*10^-2. 1010*10^-2+1010*10^-2=(1010+1010)*10^-2=10100*10^-2 Пронормируем: 10100/10=10100/1010=10*10^-1=2*10^-1=20*10^-2
> Сложите два числа 0.1+0.1

Вы спрашивали о представлении, я ответил. Теперь вы говорите о точности результатов операций с представленными значениями.
Да, пример показательный: 0.1+0.1 не то 0.2, не то 0.3, смотря куда округлять. Но точно так же вы могли получить и компенсированные отклонения.

Так вот — проблема тут не в двоичном представлении, а в точности конверсии между двумя сетками значений. Потому что — я уже тут не могу привести красивые примеры, и буду просто ссылаться на факт — когда вы с этими числами делаете не одну операцию, а сотни и тысячи, в длинных цепочках, начинают играть совсем другие факторы: а именно, насколько каждое конкретное округление после операции искажает промежуточное число. И вот тут оказывается практически всегда, что на двоичной арифметике искажений меньше, и количество точных цифр результата обычно оказывается больше, чем на десятичной.
Именно поэтому, если вы предложите матфизику считать в десятичной арифметике, он вас пошлёт куда макар телят не гонял. У него и так вечные проблемы с околонулевыми детерминантами и корректностью шага разностных схем, а тут ещё предлагают замедлиться и потерять точность ради неизвестно чего.

А если ваша цель — произвести 1-2-3 операции и получить результат предполагаемой точности… тут вообще плавучка такого вида не нужна. Обычно это финансовые операции и тому подобное, где вообще округление с потерей точности недопустимо, кроме явно обозначенных флажками мест — там плавучка вредна, надо использовать фиксированную точку. А в тех самых особых местах типа вычислить процент или квадратный корень — хватит точности double вместо single.

Десятичная плавучка в том виде, что вы предлагаете, это зверь тупо бессмысленный. Повторюсь — или двоичная, или фиксированная точка. Десятичная — или для обучения, или для тех, кто пользуется всякими SQL, но не осиливает в правильные расчёты, и хочет, чтобы SQL'ный numeric(n,m) отрабатывал (зачем-то) предельно точно.
Десятичная плавучка в том виде, что вы предлагаете, это зверь тупо бессмысленный.

А чем вид моей плавучки вас не устраивает? И чем результаты вычислений у меня отличаются от BCD-арифметики?
Надо просто привыкнуть:(.
> А чем вид моей плавучки вас не устраивает?

Не только вашей. Той, что в IEEE754-2008, тоже.
В остальном — всё сказано в предыдущем комментарии.
Мне кажется «десятичный» уже должно насторожить. Не может же такой формат быть оптимальным в системе, где все представляется в двоичном.
В СДДФ все тоже представляется в двоичном коде. Десятка выплывает только при выравнивании порядков и округлении при арифметических операциях, но и здесь число 10^n представляется в двоичном коде. Необходимость деления на 10^n или умножение на 10^-n можно отнести к накладным расходам. Это плата за точность вычислений.

Умножение на 10 это два сдвига и одно сложение. То есть можно сделать и на микроконтроллере за несколько тактов

Это делается вроде бы для точности всяких финансовых вычислений, а не для оптимальности.

С этим всё равно проблемы, описывал тут.
Десятичная плавучка выглядит странным зверем — словно для тех, кто не осиливает ни двоичную, ни фиксированную точку, но хочет суррогат. Или же для прямого перевода правил всяких SQL на машинный код со словами «вот вам сделано, к пуговицам претензии есть?»
Эх, почему у человека изначально 10 пальцев, а не 8 или 16…
IEEE754-2008 предусматривает два варианта реализации плавающей точки с десятичной степенью, первый на двоичной мантиссе, второй на двоично-десятичной в кодировке Chen-Ho. В публичных драфтах всё это есть, можете убедиться. Кстати, кодировка порядка там в обоих вариантах двоичная.
Это, кстати, к тому, что Вы постоянно некорректно называете словом «IEEE754» только ту чисто двоичную реализацию, что сейчас в каждом утюге.

Аппаратной реализации десятичной степени с двоичной мантиссой я не видел, но в GCC уже давно есть поддержка поддержка именно такого формата, делается своей библиотекой.
Можете сравнить реализацию, по скорости и прочему, но вы однозначно изобрели велосипед.
первый на двоичной мантиссе, второй на двоично-десятичной в кодировке Chen-Ho

Первый от второго отличается кодировкой ВСD-числа в формате обмена. При этом, результатом извлечения из этого формата является все тот же формат BCD. И вся десятичная арифметика строится на этом формате. Число F=М*10^e в первом случае кодируется как М и 10^e — двоичные целые числа. Во втором варианте, числа кодируются как плотно упакованные BCD. В СДДФ в формат обмена записывается двоичный эквивалент экспоненты и мантиссы.
> При этом, результатом извлечения из этого формата является все тот же формат BCD.

Из которого?
Если из второго, да, но это не тема обсуждаемой статьи. Если из первого, то никто на практике так не делает.

> И вся десятичная арифметика строится на этом формате.

Нет, не вся.

> В СДДФ в формат обмена записывается двоичный эквивалент экспоненты и мантиссы.

И ещё раз: вы в этом ничуть не уникальны.
Берём программку, которая через названную библиотеку GCC создаёт число в формате десятичной плавучки, и показывает полученное. Вот код:

Код
#include <stdio.h>
#include <stdint.h>
#include <string.h>

int main() {
  for(;;) {
    double d;
    printf("Number? "); fflush(stdout);
    if (scanf("%le", &d) != 1) {
      break;
    }
    _Decimal32 dd = d;
    //- dd = 9.999999e30df;
    uint32_t cv;
    memcpy(&cv, &dd, 4);
    printf("%08X\n", (unsigned) cv);
    puts("1|09876543210|98765432109876543210");
    for (int i = 31; i >= 0; --i) {
      putchar((cv & (1u<<i)) ? '1' : '0');
      if (i == 31 || i == 20) {
        putchar('|');
      }
    }
    putchar('\n');
    if ((cv & 0x60000000u) != 0x60000000u) {
      unsigned eb = (cv >> 23) & 0xffu;
      unsigned mant = cv & 0x7fffffu;
      printf("BE=%u E=%d M=%u\n", eb, (int)eb-101, mant);
    } else if ((cv & 0x78000000u) != 0x78000000u) {
      unsigned eb = (cv >> 21) &0xffu;
      unsigned mant1 = cv & 0x1fffffu;
      printf("BE=%u E=%d M=8388608+%u=%u\n", eb, (int)eb-101,
          mant1, mant1+8388608u);
    }
    else {
      unsigned cc = 3 & (cv >> 25);
      if (cc == 0) { printf("INF\n"); }
      else if (cc == 2) { printf("QNAN\n"); }
      else { printf("SNAN\n"); }
    }
    putchar('\n');
  }
}



Запускаем:

Лог
Number? 1
32800001
1|09876543210|98765432109876543210
0|01100101000|00000000000000000001
BE=101 E=0 M=1

Number? 2
32800002
1|09876543210|98765432109876543210
0|01100101000|00000000000000000010
BE=101 E=0 M=2

Number? 8388607
32FFFFFF
1|09876543210|98765432109876543210
0|01100101111|11111111111111111111
BE=101 E=0 M=8388607

Number? 8388608
6CA00000
1|09876543210|98765432109876543210
0|11011001010|00000000000000000000
BE=101 E=0 M=8388608+0=8388608

Number? 9999999
6CB8967F
1|09876543210|98765432109876543210
0|11011001011|10001001011001111111
BE=101 E=0 M=8388608+1611391=9999999

Number? 10000003
330F4240
1|09876543210|98765432109876543210
0|01100110000|11110100001001000000
BE=102 E=1 M=1000000

Number? 0.1
2F0F4240
1|09876543210|98765432109876543210
0|01011110000|11110100001001000000
BE=94 E=-7 M=1000000

Number? 0.2
2F1E8480
1|09876543210|98765432109876543210
0|01011110001|11101000010010000000
BE=94 E=-7 M=2000000

Number? 0.25
31800019
1|09876543210|98765432109876543210
0|01100011000|00000000000000011001
BE=99 E=-2 M=25

Number? 0.35
2F3567E0
1|09876543210|98765432109876543210
0|01011110011|01010110011111100000
BE=94 E=-7 M=3500000

Number? 1.234567e33
4012D687
1|09876543210|98765432109876543210
0|10000000001|00101101011010000111
BE=128 E=27 M=1234567

Number? 1.234567e-33
1F12D687
1|09876543210|98765432109876543210
0|00111110001|00101101011010000111
BE=62 E=-39 M=1234567

Number? 9.876543e44
7176B43F
1|09876543210|98765432109876543210
0|11100010111|01101011010000111111
BE=139 E=38 M=8388608+1487935=9876543




Ровно то, что вы рассказываете — двоичный формат представления мантиссы, двоичный формат представления порядка, но основание порядка равно 10.

Продолжайте изобретать велосипед, если так хочется, но я предупредил.
Number? 0.1
2F0F4240
1|09876543210|98765432109876543210
0|01011110000|11110100001001000000
BE=94 E=-7 M=1000000

Не многовато ли цифр для такого маленького числа, как 0.1
Жаль, что вы так и не поняли суть моего предложения. Если вы посмотрети на коменты выше, то найдете мой пример, где 0.1 в СДДФ представляется 4-х разрядной мантиссой и 2-разрядной экспонентой точно. И более того, их сложение дает точный результат. Если вас это не устраивает используйте библиотечный decimal32.
> Не многовато ли цифр для такого маленького числа, как 0.1

Просто этому коду почему-то было удобнее применить именно такой нормированный вариант.
В соседних примерах есть и другие варианты решения.

> Жаль, что вы так и не поняли суть моего предложения.

Возможно, вы не сумели её показать?

> Если вы посмотрети на коменты выше, то найдете мой пример, где 0.1 в СДДФ представляется 4-х разрядной мантиссой и 2-разрядной экспонентой точно. И более того, их сложение дает точный результат.

Верю. Но что дальше этого результата одного сложения?
Но что дальше этого результата одного сложения?

В топике, на который я ссылался в начале статьи, приведен скриншот результата работы программы 18-ти значного десятичного калькулятора, реализованного в СДДФ на C++, без привлечения специальных библиотечных функций, и результата работы Excel. В обоих случаях производится всего три арифметические операции. И если учесть, что Excel работает в строгом соответствии с IEEE754, используя дабл, то можно видеть, что далеко не всегда двоичная арифметика может удовлетворить потребности пользователя в точности.
Это не ответ.
На сейчас Вы:

1. Анонсировали разработку уровня толкового студента 2-3-го курса (просто арифметика в десятичной плавучке это именно такой уровень).

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

3. Основываетесь на результатах уровня
> В обоих случаях производится всего три арифметические операции.

в то время, как одни практические области требуют точности для цепочек миллионов операций, а другие — или вообще не допускают подобных операций (бухгалтерия), или требуют более точного определения операций (например, какое округление и почему вы выбрали для своей арифметики? можете описать свойства, преимущества и недостатки хотя бы 7 режимов округления?)

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

Рекомендуемые направления развития:
В теории: Кнут том 2 (глава 4.2.2 явно посвящена точности операций с плавающей точкой); и ещё эта классическая статья (да, я знаю, что Вы её видели — но я упомяну хотя бы для полноты комментария). Реально разберите использованную там математику, проверьте все выкладки и теоремы сами. Я что-то уверен, что вы этого ещё не сделали.
В практике: сравните вашу реализацию, как по решениям в коде, так и по результатам, с 1, 2, 3, изучите причины всех расхождений, где будут.
Далее, возьмите тест вроде решения задачи Коши на уравнении 4-й степени явным и неявным методом на равномерной сетке, при размере матрицы минимум от 1000, сравните точность на binary single, binary double и вашей арифметике. Не упоминаю пока более сложные задачи, но и этой должно хватить.

И, наконец, не допускайте явные ляпы типа сравнения
> 18-ти значного десятичного калькулятора
с
> с IEEE754, используя дабл
потому что если вы сравниваете 18 знаков своего метода против 15 гарантии на binary double, первая же ожидаемая реакция — это канделябром по выступающим деталям.

(P.S. Да, я оптимист, и готов рекомендовать всё то же самое ещё раз и ещё раз.)

Снимите корону и спуститесь на землю.
А на земле вы увидете, что (967542,3-967542,1)*10^5-19992 должно быть равно 8, а подсчитанное в двоичной арифметике в формате дабл, дает 8,0000698E+00. И это числа не с 15 цифрами, для которых результат был бы еще ужаснее. Надеюсь вам не надо объяснять почему такой результат? А если в миллионах ваших операциях встретится хотя бы сотня таких случаев, что вы получите на выходе? Или для матфизики это пыль?
P.S. Матфизику обсуждать здесь не будем. Тем более, что она появилась задолго до компьютеров с их двоичной системой счисления.

> Снимите корону и спуститесь на землю.

Давно там — я понимаю, насколько мало я знаю и использую результаты титанов (Кнут, Кахан и т.д.)
А вы?

> А на земле вы увидете, что (967542,3-967542,1)*10^5-19992 должно быть равно 8, а подсчитанное в двоичной арифметике в формате дабл, дает 8,0000698E+00.

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

> А если в миллионах ваших операциях встретится хотя бы сотня таких случаев, что вы получите на выходе? Или для матфизики это пыль?

Нет, не пыль. Но предполагать, что от точных десятичных расчётов результат вдруг станет точнее, нельзя — потому что он, наоборот, станет менее точным, за счёт более грубого округления.

> Матфизику обсуждать здесь не будем. Тем более, что она появилась задолго до компьютеров с их двоичной системой счисления.

И что меняется от времени её появления?
И что мы тогда будем обсуждать? Определите точную область. Вариант «расчёты в Excel» не годится по определению, это не область, а конкретное средство.
Какая область? Бухгалтерия? Логистика? Финансы? Графика?
Давно там — я понимаю, насколько мало я знаю и использую результаты титанов (Кнут, Кахан и т.д.)
А вы?

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

Но предполагать, что от точных десятичных расчётов результат вдруг станет точнее, нельзя — потому что он, наоборот, станет менее точным, за счёт более грубого округления.

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


Точность — степень приближения истинного значения рассматриваемых параметров изделия, вещества, системы или процесса к истинному или теоретическому номинальному значению (1). Поскольку точное десятичное значение дробного десятичного числа в двоичном представлении принимает приближенное значение, то первое число-точное, а второе приближенное. Дело вкуса (или по другим соображениям), какими числами оперировать. В любом случае, с точными числами, если нет ограничений по разрядной сетке, мы будем получать точные результаты, а с приблизительными — приблизительные. Последние склонны к накоплению ошибки.
И что мы тогда будем обсуждать?

Компьютерную арифметику.
> Поскольку точное десятичное значение дробного десятичного числа в двоичном представлении принимает приближенное значение, то первое число-точное, а второе приближенное.

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

Контексты, где эта посылка верна, хорошо известны, и плавающая точка для них в принципе слабо применима из-за других проблем, таких, как плановая потеря точности там, где она в принципе не допускается. Исключения вида «предписано стандартом SQL» уже называл.

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

> то первое число-точное, а второе приближенное.

Исходя из предыдущего абзаца, там, где десятичная плавучка вообще используется, она чаще всего представляет собой результат перекодирования предыдущего результата двоичных расчётов. Поэтому именно двоичное число является более точным.

> В любом случае, с точными числами, если нет ограничений по разрядной сетке, мы будем получать точные результаты,

Ограничения эти есть всегда. И все реальные расчёты в плавучке (не в тщательно подобранной песочнице) будут упираться в эти ограничения, и будет потеря точности.

> Компьютерную арифметику.

Всё меньше вижу смысла: вы её не понимаете.
Послушайте, может хватит говорить лозунгами и оскорблениями? Или в матфизике это принятый стиль ведения дискуссии? Меня в универе на физфаке учили другим этическим нормам. Нас учили использовать математику, а не разговоры о ней.
> Нас учили использовать математику, а не разговоры о ней.

Простите, а почему вы тогда её не используете?
Я как раз от вас слышу сплошные лозунги.

> Или в матфизике это принятый стиль ведения дискуссии?

«В матфизике» обычно смотрят на доказательства, и не используют методы, которые заведомо портят точность.
Простите, а почему вы тогда её не используете?
Я как раз от вас слышу сплошные лозунги.

Если некая фигура имеет форму окружности с радиусом 1м. То, глядя со стороны, кажется, что это круг, который имеет площадь pi*r^2=3.142м^2. На самом деле, площадь, которую она занимает равна 2pi*r*h, где h=1мм=0,001м, это толщина линии, описывающей круг. В результате, реальную площадь, которую занимает эта фигура, с точностью до 3 значащих цифр равна 0.00629м^2.
Это требует доказательств? Подсчитано на калькуляторе в СДДФ.
> с точностью до 3 значащих цифр равна 0.00629м^2.
> Это требует доказательств? Подсчитано на калькуляторе в СДДФ.

С точностью до 3 значащих цифр, 3.1415926… * 2 будет округлением 6.2831… что даст 6.28, а не 6.29.

Что-то неладно в датском королевстве вашем калькуляторе.
Подсчитано на калькуляторе в СДДФ.

Это был сарказм. Считал в уме.
Насколько точнее представление числа Пи в СДДФ по сравнению с двоичным? Или речь идёт о конкретном десятичном округлении этого числа, а не о настоящем Пи?
Настоящее пи — число иррациональное и в десятичном коде точно представлено быть не может. Для разных нужд его округляют до разного количества значащих цифр. Для вычислителя (назовем его калькулятором) округленное число пи является точным. Он ничего не знает о природе его происхождения. Нам хотелось бы, чтобы это число далее точно сохроняло свое значение. Как работать с десятичными числами мы знаем. Но, выбирая двоичную арифметику, мы вносим в его значение ошибку представления. В двоичном числе появляются неверные цифры, которые влияют на точность дальнейших вычислений. Чтобы влияние было меньше, двоичное число должно быть представлено наиболее близко к своему десятичному эквиваленту. Для обеспечения этого требования мы вынуждены повышать разрядность операционного региста до 64,128, 256 разрядов и т.д. При этом неверные цифры, полученные за счет преобразования, все равно оказывают влияние на точность вычислений. В итоге, из N-разрядного числа после ряда вычислительных операций, верными оказываются приблизительно N/2 десятичных цифр. Поскольку СДДФ
реализовывает десятичную арифметику, то округления производятся для десятичных чисел, в которых убираются неверные цифры в соответствии с теорией вычислений.

Т.е., необходимость в СДДФ вытекает из неверно поставленной задаче о сохранении точности в десятичном формате. Ок.

Необходимость СДДФ вытекает из достижения максимальной производительноти и точности минимальными средствами.

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

Понятие точности имеет вполне определенное научное определение.

… в котором нигде не сказано, что "максимальная точность" достигается только в десятичной системе счисления. О чем и речь.

Там вообще ничего про системы счисления не сказано. Там сказано, в вольном переводе, что чем объект ближе к своему номинальному значению, тем он более точен. В нашем случае, чем двоичное число более близко по своему значению к своему номинальному значению, а в нашем случае это десятичное число, тем оно более точно представляет это десятичное число.
В нашем случае, чем двоичное число более близко по своему значению к своему номинальному значению, а в нашем случае это десятичное число

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

другие люди могу решать задачу максимального приближения измерения

Правильно, кто-то меряет в попугаях и его это вполне устраивает

А почему, собственно, нет?

Так я ж не против. Змей только будет возмущаться, что принизили его значимость.
Для вычислителя (назовем его калькулятором) округленное число пи является точным. Он ничего не знает о природе его происхождения. Нам хотелось бы, чтобы это число далее точно сохроняло свое значение.

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


Но, выбирая двоичную арифметику, мы вносим в его значение ошибку представления.

А значит, никакой ошибки представления нет.

Мое утверждение: «Но, выбирая двоичную арифметику, мы вносим в его значение ошибку представления»
Ваше утверждение:
А значит, никакой ошибки представления нет.

Это как понимать?

Так и понимать: вы совершили ничем не объяснимый логический скачок от "вычислитель работает с точными числами" к "точные числа должны быть десятичными". А они никому этого не должны.

Где вы эти слова то нашли в моих текстах?

Вы их уже цитировали. Но если хотите, могу повторить логическую цепочку еще раз.


Примем за догму, что "для вычислителя (назовем его калькулятором) округленное число пи является точным" (на самом деле, это далеко не всегда так, но для простоты так и оставим). Итак, число на входе вычислителя — точное.


Наша задача — "чтобы это число далее точно сохроняло свое значение".


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


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

(потому что реализационные задачи вообще без ограничений не решаются, смысла) нет.

Извините, скобочка уехала, должно быть "смысла нет)".

Извините, мне трудно разобраться с текстом, где в цитаты оппонента вставляются свои, как вам кажется правильные слова. За неимением времени, если вы хотите разобраться с вопросом, а не доказать любыми способами, что автор верблюд, прошу в личку.

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


Так что хорошая попытка, но нет.

Нам известно, что вычислитель — двоичный (это тоже условие задачи).

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

Если вам неизвестно, то у вас другие условия задачи, о чем я вам и говорю.


Для обоих случаев ошибок представления нет.

Что и требовалось доказать.

Если вам неизвестно, то у вас другие условия задачи, о чем я вам и говорю.


А мы разве где-то обсуждали условия задачи? Я все время говорил про инструмент.

Для обоих случаев ошибок представления нет.

Что и требовалось доказать.

А я где-то утверждал обратное?
Хотите истины, прошу в личку.
Я все время говорил про инструмент.

А инструмент подбирается под условия задачи или определен условиями задачи. Обсуждать его отдельно смысла нет.


А я где-то утверждал обратное?

Да: "выбирая двоичную арифметику, мы вносим в его значение ошибку представления".

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

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

Именно! И почему-то вы считаете, что ваши ожидания — правильные, а мои — нет.

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

Вы не умеете проверять на бумаге двоичные вычисления? Странно, это ничем не сложнее десятичных, просто непривычно.


Другое дело, что это бессмысленно: вы все равно не сможете (в разумных рамках) проверить на бумаге расчет попарных косинусных расстояний для полумиллиона векторов размерности 500+ (это я прямо из соседнего окна подглядываю), так зачем вообще к этому апеллировать?

Вы не умеете проверять на бумаге двоичные вычисления? Странно, это ничем не сложнее десятичных, просто непривычно.

У меня складывается впечатление, что вы читаете не то, что написано, а то, что хотите видеть в написаном.
К СДДФ это не имеет никакого отношения
К СДДФ это не имеет никакого отношения

Тогда зачем вы приводите этот аргумент?

Какой?

"я ожидаю получить результат, который могу проверить на бумаге, как меня учили в школе"

Если вы не доверяете вычислителю, у вас имеются другие варианты проверки результата?.. Странно пользоваться вычислителем для серьезных эадач, который на простых примерах дает неверный результат.
Прошу в личку.
Если вы не доверяете вычислителю, у вас имеются другие варианты проверки результата?..

Да, рассчитанные другим вычислителем, о котором известно, что он корректен.

В матфизике» обычно смотрят на доказательства, и не используют методы, которые заведомо портят точность.

В десятичной арифметике есть три основных обязательных свойства для сложения и умножения: коммутативный, ассоциативный, дистрибутивный. В арифметике с плавющей двоичной точкой выполняется только коммутативный.
И вы утверждаете, что такой ущербной арифметикой можно производить вычисления более точно?
> В арифметике с плавющей двоичной точкой выполняется только коммутативный.

Это грубо неверно. В арифметике с base=10 точно так же не выполняется уже и ассоциативный закон. Простейший пример:

    _Decimal32 a = (_Decimal32)9999999;
    _Decimal32 b = (_Decimal32)4;
    _Decimal32 c = (_Decimal32)3;
    _Decimal32 r1 = a + (b + c);
    _Decimal32 r2 = (a + b) + c;
    printf("%.0lf %.0lf\n", (double) r1, (double) r2);


Запускаем:

10000010 10000000


Результат 9999999+4, равный 10000003, не влез в 7 цифр и был округлён до 10000000. Следующая сумма точно так же была округлена.

Примеры для своей самопальной реализации найдёте сами, за отсутствием публичного кода.

Аналогично и с дистрибутивным законом: никакая арифметика с округлением до фиксированного числа точных разрядов, с любым основанием, не соответствует ему.

> И вы утверждаете, что такой ущербной арифметикой можно производить вычисления более точно?

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

Под двоичной арифметикой имеется в виду именно двоичная, а не то, что получается из вашего постоянного некорректного трюка «переквантуем точные десятичные значения в двоичку, выполним 1-2 операции, переквантуем обратно и будем смаковать отклонения в результате».
Это грубо неверно. В арифметике с base=10 точно так же не выполняется уже и ассоциативный закон

Скажите такое математикам (не матфизикам) и они вам «канделябром по выступающим местам», так по-моему вы изволили выразится в коменте выше.
В маниакальной попытке доказать, что вы самый, вы совершенно не вникаете в те доводы, которые я вам привожу и спорите сами с собой.
> Скажите такое математикам

Они знают и подтверждают. См. те же базовые источники.

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

Я честно вникаю. Что же по поводу маниакальности — я просто промолчу, чтобы не переходить на ответные личности… ;)
Они знают и подтверждают. См. те же базовые источники.

Вы ссылветесь на компьютерную арифметику, а я на арифметику «обычную».
Что же по поводу маниакальности — я просто промолчу, чтобы не переходить на ответные личности…

Вынужден был так написать, чтобы призвать вас к корректности ведения дискуссии. Вы считаете «канделябром по...» менее оскорбительно, чем слово «маниакально»?
Кстати, вы пропустили вопрос про область применения вашей арифметики.
Область применеия арифметики — арифметические вычисления.
Все, я устал.
А на земле вы увидете, что (967542,3-967542,1)*10^5-19992 должно быть равно 8, а подсчитанное в двоичной арифметике в формате дабл, дает 8,0000698E+00

Что равно 8 с заданной для задачи точностью, в чем проблема-то?

А где в задаче была определена точность? Поскольку числа в дабл, то хотелось бы и точность ответа с 15 значащими цифрами на выходе?
А где в задаче была определена точность?

Там, где все значения были с точностью не более одного знака после запятой.


Поскольку числа в дабл, то хотелось бы и точность ответа с 15 значащими цифрами на выходе?

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

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

Если бы вы внимательно прочитали эту мою статью и статью предыдущую, то вы бы увидели, что для получения результата с точностью до 7 значащих десятичных цифр при вычилениях, при использовании СДДФ достаточно 32-х разрядного слова. А для 64 разрядах машинного слова все вычисления проводятся с точностью до 16 верных значащих цифр. В строгом в соответствие с теорией приближенных вычислений.
Если бы вы внимательно прочитали эту мою статью и статью предыдущую, то вы бы увидели, что для получения результата с точностью до 7 значащих десятичных цифр при вычилениях, при использовании СДДФ достаточно 32-х разрядного слова.

Это как-то противоречит моему высказыванию?

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

И что? Вы мне хотите сказать, у вас накопления ошибки не происходит принципиально?

Да, не происходит.
Аппаратной реализации десятичной степени с двоичной мантиссой я не видел, но в GCC уже давно есть поддержка поддержка именно такого формата, делается своей библиотекой.

Кино я не смотрел, но оно мне не нравится.
Для тех, кто читал предыдущую статью по этой теме, эта статья — прямо как от Капитана Очевидность.
Как-то тоже встала задача вписать в 64 бита и дроби десятичные и целые. Отдал под экспоненту 1 бит, младший. Либо 0 либо -6. И сверху всё в операциях ограничил 18 десятичными разрядами. Т.е. если по модулю число < 10^12, то 6 знаков после запятой без потерь. Если больше, дробная часть откидывается и число может достигать значения до 10^18. 18 десятичных разрядов влезают в 60 бит, т.е. за вычетом знака есть ещё пара битов про запас. И это тоже оказалось полезным. Для сериализации сложил знак и экспоненту в младшие 4 бита, остальное, соответственно мантисса. И всё это добро всё ещё вписывается в 64 бита, т.е. может быть достаточно компактно закодировано например в 7 битный protobuf uint64.
Автор с 16го года жуёт одну и ту же тему и наконец-то понял, что дробные двоичные это деление на 2, а дробные десятичные это на 10 и то, что нацело делится на степень 10, не всегда делиться на степень 2. Разьве не очевидно, что заменив степень двойки на степень десятки убираются деления на 2, в чём полезная информация? Статью-то зачем было писать, прошлых не достаточно? Пруф: коммент 16го года
Вы просто гений!!!, Сходу все расставили по полочкам. А то я, на протяжении нескольких лет, именно это и пытался доказать!
Откуда точность СДДФ в 7 десятичных знаков?
По моим представлениям, она всего 3 десятичных знака (при благоприятных условиях «почти 4»)
Я не могу здесь дублировать свою предыдущую статью. Если вычисления (именно вычисления) проводятся в формате сингл, то так оно и получается, 3,4 знака. А в СДДФ получаются 7 верных десятичных знаков в результате любых вычислений.
Как будут представлены в СДДФ числа 10000 и 10001?
Как могут вычисления обеспечивать точность в 7 знаков, если формат, который в них используется, умеет хранить только 3?
Внимание, спойлер: если даже вычисления обеспечивают задекларированную точность, она будет потеряна при выдаче результата
формат, который в них используется, умеет хранить только 3?

Это вы про какой формат? Котрый был приведен выше, для суммы 0.1+0.1?
Для одноразрядных десятичных чисел достаточно 4 разряда мантиссы. Для чисел 10000 и 10001 достаточно 17 разрядов мантиссы для точного их представления.
Про тот СДДФ, который описан в статье, про который Вы говорите в статье
Точность представления вещественных десятичных чисел равна 7 значащим десятичным цифрам.

если я ничего не напутал.
Для чисел 10000 и 10001 достаточно 17 разрядов мантиссы для точного их представления.

А у Вас в СДДФ только 10
Цитата верна, но про формат, в котором можно хранить только 3 знака, я ничего не знаю.
СДДФ с мантиссой 10 бит умеет хранить только 3 (для отдельных значений «почти 4») знака, как и сказано выше
Откуда точность СДДФ в 7 десятичных знаков?
По моим представлениям, она всего 3 десятичных знака (при благоприятных условиях «почти 4»)

Это ваши слава?
А вот был мой ответ
Я не могу здесь дублировать свою предыдущую статью. Если вычисления (именно вычисления) проводятся в формате сингл, то так оно и получается, 3,4 знака. А в СДДФ получаются 7 верных десятичных знаков в результате любых вычислений.

Где здесь про 10 бит и три знака?
Нормализованная мантисса в СДДФ является целым двоичным числом равным эквиваленту десятичного числа, которое в нашем случае представлено тремя цифрами: UХХ. Где U — любая десятичная цифра не равная нулю. Х — любая десятичная цифра.

В 10 битах мантиссы может быть представлено максимальное десятичное число 1023. Все целые числа меньше 1023 могут быть гарантировано представлены 10 битами. Следовательно, все целые десятичные числа с мантиссой ≤ 999 могут быть точно представлены 10 битами мантиссы.

Гарантированое количество верных цифр, которое можно представить двоичной 11-ти битной мантиссой равно 3.

Точность представления вещественных десятичных чисел равна 7 значащим десятичным цифрам.

Все цитаты из этой статьи

P.S. Не можете привести цитату из статьи, намекните хотя бы, из какой именно
Первая цитата под одной вертикальной линией относится к СДДФ с 16-разрядным машинным словом.
Вторая цитата, вместе с сылкой на источник, относится к формату половинной точности IEEE754.
Третья цитата относится к СДДФ с 32-х разрядным машинным словом.
Как это можно было понять до этого вашего комментария?
(про вторую цитату несогласен, она с определёнными оговорками универсальна)
Как это можно было понять до этого вашего комментария?

Внимательно почитать статью.
(про вторую цитату несогласен, она с определёнными оговорками универсальна)

Оговорки такие. В формате IEEE754 11-ю двоичными разрядами можно приближенно представить 3-х разрядное десятичное число, в котором 3 верные десятичные цифры. В СДДФ 11-ю разрядами можно точно представить 3-х разрядное десятичное число.
Внимательно почитать статью.

Кто бы её аккуратно написал
Буду благодарен, если вы укажете на слабые места в статье.
Судя по этому комментарию, нет, не будете: в нём, как раз, указаны слабые места
Если в статье имеются ошибки, неточности, некорректно сформулированные утверждения, и вы на них укажете, почему вы считаете, что я не буду благодарен. Очень даже буду. Но если вы ругаете статью только за то, что она не соответствует вашим представлениям, без анализа вышеперечисленных факторов, то да, спасибо не скажу. Арифметика -наука точная. Доказательства в ней ведутся с помощью оперирования числами, а не общими рассуждениями.
Вы говорите про математику, но почему-то называете её арифметикой.
При чём здесь вообще математика или арифметика?
Вам указали на вполне конкретный недостаток статьи, а именно, полное отсутствие уточнений, о какой именно из разновидностей СДДФ идёт речь в каждом конкретном случае, однако, вы упорно делаете вид, что вам просто говорят что-то вроде «статья никуда не годится», никак не указывая на то, что именно не так.
Вы говорите про математику, но почему-то называете её арифметикой.

Арифметика — это подраздел математики. Компьютерная арифметика — это подраздел классической арифметики. Я говорю о компьютерной арифметике, используя понятия классической арифметики.
При чём здесь вообще математика или арифметика

Действительно, если читать только комментарии отдельных авторов, то математики и арифметики в них можно и не найти.
Вам указали на вполне конкретный недостаток статьи, а именно, полное отсутствие уточнений, о какой именно из разновидностей СДДФ идёт речь в каждом конкретном случае,

А можно примеры этих случаев? Где в статье рассматриваются «разновидности СДДФ», без уточнений, конкретных примеров или где в наличии двусмысленности. Я поправлю.
В данной статье НИГДЕ не уточняется, о какой разновидности СДДФ идёт речь, что и вызвало мой вопрос в начале этой ветки
В статье написано.
«Сравним основные свойства чисел с плавающей точкой, которые представлены в стандарте IEEE754 и СДДФ. Для простоты рассмотрим 16-разрядное машинное слово. Это так называемый формат половинной точности.» Это преамбула для сравнения половинного формата IEEE754 c СДДФ, закодированном в 16 разрядном машинном коде. Дале с 1 по 12 раздел сравниваются представления чисел только для указанных форматов. В заключение указаны основные свойства чисел представленных в формате сингл IEEE и СДДФ с 32 разрядным машинным словом. Какие уточнения еще требуются?
> Как могут вычисления обеспечивать точность в 7 знаков, если формат, который в них используется, умеет хранить только 3?

У топикстартера одним и тем же термином называются форматы на 3, 7, 16, 18 десятичных цифр, в разных местах и вразброс, их характеристики вспоминаются без уточнения конкретного формата.
Формат двоичных чисел с фиксированной точкой может быть реализован в 16,32,64 разрядном машинном слове. СДДФ также может быть реализован в словах различной разрядности. Пока он не попадает ни под какие стандарты.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории