Найти в Дзене
KVY

Float320

Чисто ради прикола, попробовать собственные силы, решил реализовать такой тип. Много ли еще таких безумцев, занимающихся мало кому нужной бессмысленной работой? Я знаю только одну компанию - Apple, которая таки реализовала Float256. То есть тут я даже их чуть-чуть переплюнул. ) Обе реализации, и моя, и Apple, не соответствуют IEEE 754. В этом стандарте нет точности в 320 бит, а число в 256 бит имеет мантиссу длиной в 236 бит (237 бит явно не хранится в числе) и порядок в 19 бит. В то время как Apple сделала более удобный для реализации тип, в котором у мантиссы 224 бита, причем она представлена в дополнительном коде, и порядок в 32 бита. Я же выбрал 320 бит для того, что бы число вписалось в целое количество 8-байтных слов, и обработку я веду фактически тоже такими словами. В результате у меня получилась порядок вместе со знаком числа занимает 64 бита, а мантисса - 256 бит. Apple, судя по статье в википедии, смогла реализовать только три арифметических операции: сложение, вычитание и у

Чисто ради прикола, попробовать собственные силы, решил реализовать такой тип.

Много ли еще таких безумцев, занимающихся мало кому нужной бессмысленной работой? Я знаю только одну компанию - Apple, которая таки реализовала Float256. То есть тут я даже их чуть-чуть переплюнул. )

Обе реализации, и моя, и Apple, не соответствуют IEEE 754. В этом стандарте нет точности в 320 бит, а число в 256 бит имеет мантиссу длиной в 236 бит (237 бит явно не хранится в числе) и порядок в 19 бит. В то время как Apple сделала более удобный для реализации тип, в котором у мантиссы 224 бита, причем она представлена в дополнительном коде, и порядок в 32 бита.

Я же выбрал 320 бит для того, что бы число вписалось в целое количество 8-байтных слов, и обработку я веду фактически тоже такими словами. В результате у меня получилась порядок вместе со знаком числа занимает 64 бита, а мантисса - 256 бит.

Apple, судя по статье в википедии, смогла реализовать только три арифметических операции: сложение, вычитание и умножение. Я же тут Apple обставил, так как у меня еще есть и деление - самая сложная в реализации арифметическая операция!

Есть и другие отклонения от стандарта:

  • обратное стандарту толкования знака числа: установленный бит в старшем разряде означает положительное число, а его отсутствие - отрицательное; сделано для ускорения операций сравнения чисел между собой;
  • первый бит мантиссы, который всегда равен 1, хранится явно, в отличие от реализаций стандарта, где у мантиссы первая единица всегда убирается: при такой точности глупо экономить 1 бит, теряя в производительности на постоянных операциях сдвига туда-сюда при выполнении арифметических команд;
  • при такой точности (примерно 77 десятичных знаков) я решил, что смысла поддерживать денормализованные числа нет никакого;
  • не реализовано округление для арифметических операций из-за соображений производительности; хотя реализовать не очень трудно и сильно производительность округление не снизит; но пока так, и это нужно учитывать, так как при использовании некоторых численных методов ошибка может накапливаться; если вдруг у кого-то будет запрос, то могу со временем сделать поддержку округления.

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

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

Впрочем, если от кого-то будет запрос, то это простимулирует меня продолжить работу в этом направлении. Также как и реализовать какие-нибудь элементарные функции. Какие более важны? Корни, тригонометрия, экспоненты или логарифмы?

Теперь о производительности. На простейшем тесте моя реализация дает примерно 38-39 МФлопс на Ryzen7 5800X. Много это или мало? Честно говоря не знаю, так как сравнивать особо не с чем.
Могу лишь сказать, что примерно каких-то 30 лет назад такую производительность выдавали топовые микропроцессоры на типе
double.
Но
Float320 настолько велик, что в регистры процессора не помешается, поэтому большое значение (особенно с учетом тонкости реализации операторов на Delphi) имеет производительность памяти, особенно кэша первого уровня.

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

В шестнадцатеричном варианте число выглядит так (от старшего слова - порядок, затем мантисса):
$C000000000000000;$C90FDAA22168C234;$C4C6628B80DC1CD1;$29024E088A67CC74;$020BBEA63B139B22;
Первое слово определяет знак и порядок: положительное число, двоичный порядок равен единице, а значит в мантиссе записано
Пи пополам. По идее, это значение более точное, чем десятичное, но что-то сходу точное длинное значение числа Пи в шестнадцатеричном виде не нашел, а самом считать лень, что бы точно понять какая ошибка в последнем разряде.

Модуль на Delphi можно скачать здесь, вместе с модулем UInt128: он потребуется для компиляции. UInt128 я использую для преобразований типов, хотя может и зря. Может быть, ограничившись 64-битным типом, получилось бы быстрее.

Пользоваться модулем можно свободно, но ссылка на автора, то бишь меня - обязательна. Но и от донатов для продолжения работы тоже не откажусь ;)