Альтернатива стандарту IEEE754

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

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

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

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

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
















    Поделиться публикацией

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

      +5
      Текст картинкой?! o_O
        +1
        Автор, похоже, поленился набивать формулы недружелюбным для этого средством. В целом, решение вполне здравое ;-)
          +2
          А чего стоят ссылки картинкой
          +2
          А зачем вместо обычного текста, в посте картинки с текстом? Вы боитесь, что кто-то скопирует ваши измышления и выдаст за свои? Так если захотеть, то можно и картинку распознать.

          P.S. Я всегда буду обновлять комментарии перед отправкой своего.
            +3
            Да нет, просто мне администрация Хабра на мой вопрос, «как публиковать формулы» ответила, что только используя изображение. А поскольку формул много, в целях экономии времени, я весь текст в картинки перевел.
              +5
              Я думаю из уважения к читателю стоило бы опубликовать материал в pdf, а пост оформить как введение и дать ссылку на скачивание. Сама тема то интересная, но подача материала мешает восприятию.
                +1
                Спасибо, я так и попробую сделать. Ссылку предоставлю.
                0
                Есть онлайн-редакторы, которые позволяют это делать довольно быстро, например latex.codecogs.com/eqneditor/editor.php, или даже специализированные инструменты, как вот тут habrahabr.ru/post/263213
                  0
                  Текст в PDF можно посмотреть по ссылке yadi.sk/i/UYfZjfNakwFoM
                    0
                    На Хабре не работает поиск ни по тексту на картинке, ни по пдфкам в ссылках.
                0
                Для формул из статьи вполне достаточно и обычного HTML и википедии: https://en.wikipedia.org/wiki/Mathematical_operators_and_symbols_in_Unicode

                Чтобы не быть голословным: http://jsfiddle.net/q9xfj9b0/
              0
              По-моему логично, что работа с денормализованными числами в IEEE не сложнее работы с предлагаемыми ненормализованными числами
                0
                Для программиста, с точки зрения написания кода, это видимо не сильно заметно.
                Но согласно данным, приведенным в работе. charm.cs.illinois.edu/newPapers/06-13/paper.pdf (См. TABLE II
                WORST CASE SLOWDOWNS ON OUR SUBNORMAL SLOWDOWN
                MICRO-BENCHMARK ON COMMON MICRO-ARCHITECTURES) использование денормализованных чисел существенно замедляет работу процессора. А там, где она сведена к минимуму, это достигается большими аппаратными затратами.
                  0
                  я про реализацию на уровне железа
                    0
                    Денормализованные, или субнормальные числа в IEEE отнесены к особому случаю и обрабатываются по особым алгоритмам. И алгоритмы эти в сопроцессоре существенно отличаются от работы с нормализованными числами.
                      +1
                      Вот, а у меня после прочтения сложилось впечатление, что вы этот алгоритм предлагаете использовать всегда.
                        0
                        О каком алгоритме идет речь? Если не использовать специально нормализацию, то работа с нормализованными и денормализованными числами ничем не будет отличаться. Они будут обрабатываться по одним и тем же алгоритмам.
                          0
                          Извините, я сразу не понял о каком алгоритме идет речь. В алгоритме, который я предлагаю, нет разницы между нормализованными и ненормализованными числами. Поэтому нет особого случая. Все числа обрабатываются одинаково. В том же случае, когда порядок числа по абсолютной величине превышает максимальное значение, которое может он принимать, наступает переполнение.
                            0
                            Я лишь говорю, что ваш алгоритм соответствует по сложности алгоритму работы с денормализованными числами в IEEE. В любом случае, без сравнения конкретных алгоритмов или их железной реализации, это лишь впечатление, которое может быть неверным.
                0
                Современные архитектуры уже позволяют оперировать очень большими числами, соответственно, нет никаких проблем расширить диапазон чисел, включив туда рациональные и оперировать дробями. На числитель и знаменатель по 64 бита, это будет очень хороший диапазон, двигать туда сюда мантиссу не вижу смысла, многие проблемы отпадут, а от погрешностей никуда деться всё равно не получится.
                По поводу погрешностей, вы делаете очень много упрощений.
                Вот есть два числа:
                1.00X
                2.99X
                здесь два знака после запятой посчитаны точно, в третьем знаке мы не можем быть уверены (обозначено как X).
                По вашей методике округлять до двух знаков нет смысла, поскольку мы будем приближать не к точному значению, а к случайному, ведь не зависимо от того, чему равно X (5, к примеру) посчитанное точно оно может быт и 0 и 9. Поэтому что бы не отбрасывать. а округлять, надо считать +1 разряд точно, а это уже проблема серьёзная и на практике малоосуществимая.
                Теперь складываем 1.00X+2.99X и мы не можем записать 3.99X в результат. потому что X+X может быть больше 9, а значит, если бы мы считали с большей точностью, то получили бы 4.00X фактически мы теряем при сложении ещё один разряд точности и надо записать 3.9XX, на практике же, любые девятки ещё более ухудшают наше положение и реально мы получим X.XX
                Про умножениях всё ещё хуже: 0.1X*10000= 1XXX.X точность была до десятичных, а после умножения можно уже не заморчиваться и считать тысячами, всё остальное отдано рандому.
                Поэтому не вижу смысла вообще заморачиваться с точностью представления чисел, надо вычисления делать таким образом, что бы минимизировать ошибку, вот основной посыл.
                  0
                  Все, что касается десятичной арифметики, Вы все правильно написали. Но, в моей статье идет речь о попытках решения арифметических десятичных задач с использованием двоичной арифметики. Когда мы считаем на калькуляторе, он не знает природу происхождения цифр, точные они или приблизительные. Он честно выдает тот результат, который должен быть получен по правилам арифметических действий в пределах своей разрядной сетки. Для калькулятора это точные числа. Только мы знаем природу этих чисел и дальше поступаем с ними так, как считаем нужным, например так, как в вашем примере. Но, когда мы два точных дробных числа преобразуем в двоичные ЧПТ, чтобы быстро посчитать, мы из точных десятичных получаем приблизительные десятичные, которые содержат верные и неверные цифры. Влияние этих неверных цифр приводит к серьезным погрешностям. Чем длиннее двоичная мантисса ЧПТ, тем дальше отодвигаются неверные числа и меньше влияют на получение верных цифр при арифметических действиях. Но в любом случае хвост оказывает влияние на результат и существенно сужает диапазон точности. И есть такие случаи, когда это влияние становится столь велико, что наш инструмент становится непригоден для использования. Беда в том, что эти случаи очень трудно обнаружить.
                    0
                    В двоичных проблемы все те же самые. И вы слишком зациклились на точных числах, вам уже подсказывали что числа почти всегда это результат вычислений и в общем случае могут быть точными только до какого-то знака, не важно двоичная это или десятичная. Так же вы полностью проигнорировали моё высказывание о дробях. Я говорю это не просто так, дроби позволяют точно представлять рациональные числа. ТОЧНО. Все эти ваши 0.(3) и т.п. не важно в сколькиразрядных системах счисления.
                    А самое главное, вы проигнорировали вот этот пункт: «надо вычисления делать таким образом, что бы минимизировать ошибку, вот основной посыл. „
                    Как только вы начинаете преобразования чисел у вас сразу пропадет понятие “точно», потому что если вы не можете точно записать ответ, то вы просто фиксируете ошибку: «ответ не точный начиная с..» и возвращаетесь к сути которую я пытаюсь донести — рассматривайте операции погрешности, которые они вносят, а не «зафиксированные погрешности» и всё встанет на свои места, а где-то можно будет даже уменьшить итоговую погрешность в операциях.
                      0
                      Если же для вас принципиальна только десятичная система. то есть, так называемое двоичнодесятичное преобразование (каждый разряд — 4 бита, тетрада), позволяющее с маленькими накладными расходами вести вычисления именно в десятичных разрядах, просто используйте это и вносимые погрешности в операциях будут десятичными, а не двоичными. но они никуда не денутся. Кстати. не факт, что ваш калькулятор это использует, возможно он просто использует FixPoint и за счёт отсутсвия нормализации пропущена часть операций, поэтмоу погрешность меньше но она тоже двоичная, только и всего.

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

                  Самое читаемое