Арифметические операции над числами с плавающей точкой

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

Когда-то на втором курсе университета я познакомился как раз с одной из вещей, которую, по-моему, должен знать каждый из нас, ну или хотя бы услышать о ней вот в такой статье. Это стандарт представления чисел в формате с плавающей точкой(в других источниках с плавающей запятой). Как же въелось мне это название: стандарт IEEE-754.

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

Итак, что же такое этот стандарт IEEE-754? Скажу сразу, что нам в университете дали его в электронном виде на русском, но в интернете я не смог его найти, даже дойдя до 30-й страницы гугла. Был пример на английском, в котором автор писал его в 4:36 АМ. Я даже нашёл сайт, в котором говориться, что если бы Сатана решил захватить Землю медленно, он бы создал этот стандарт. Но его создали люди, такие же, как и мы с вами.

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

По этому предмету в университете у нас рассчитывалась РГР (Расчётно-Графическая работа) и почему то тогда я понял, что стоит ей уделить больше времени, чем чему-либо и оказался прав. Это, наверное, был переломный момент моей учёбы. Я сидел ночами над этим стандартом и над конкретно поставленной передо мной задачей: «Деление двух чисел в формате с плавающей точкой двойной точности с заменой цепочек непрерывных единиц нулями и с округлением до ближайшего чётного». Тогда это нельзя было понять. И стандарт IEEE-754 всегда следовал рядом с этим заданием. На самом деле там было всё, абсолютно всё, что мне нужно было.

Ну, а теперь подробнее собственно, о стандарте IEEE-754. Он представляет собой несколько глав, которые я хотел бы описать поподробнее.
Всё как всегда начинается с введения. О том, что существуют программы, намного сложнее чем то, что я видел. Рассказывается об истории создания стандарта. Ведь программы становятся всё сложнее и сложнее, а ЦВМ стареет и следует заменить её новой архитектурой. Это послужило причиной тому, что IEEE (Институт инженеров по электротехнике и электронике США) в конце 70-х годов создал комиссию, рассмотревшую множество предложений. Результатом работы комиссии явился стандарт IEEE 754 ≪Двоичная арифметика с плавающей точкой≫ (1985г.), ставший международным. Его основы разработал профессор математики университета Беркли William Kahan.
В последующие годы на базе IEEE 754 – 1985 были разработаны стандарты:

— IEEE 854 – 1987, покрывающий десятичную арифметику также как и двоичную;

— IEC 60559 — 1989 IEC ≪Двоичная арифметика с плавающей точкой для
микропроцессорных систем≫ (IEC — International Electrotechnical Commission).

Стандарт IEEE 754 не обязывает, а рекомендует применение пакета оговоренных в нем форматов, способов кодирования данных, округления результатов и многое другое. Задача выбора формата для конструктора универсальной ЦВМ предельно упростилась, и с этого времени фирмы стали производить универсальные ЦВМ с арифметикой с плавающей точкой удовлетворяющей рекомендациям стандарта. Задача программистов также несколько упростилась, т.к. нет необходимости изучать особенности двоичной арифметики с плавающей точкой разных ЦВМ, достаточно овладеть знанием стандарта.
Но нужно помнить, что стандарты консервативны, но не вечны. И, тем не менее, этим стандартом пользуемся все мы с вами, коллеги.

Стандарт поддерживает несколько форматов: одинарная точность(32 разряда), двойная(64 разряда) и двойная расширенная точность. Так же предусмотрены другие форматы для предотвращения ошибок округления и т.д. В стандарте описаны случаи возникновения исключительных ситуаций: Nan, бесконечность, деление на ноль и т.д. Ничего не напоминает? Очень важную роль играет округление чисел в формате с плавающей точкой. Это тоже описано в стандарте.

И наконец-то, главный раздел – Выполнение операций над числами в формате с плавающей точкой. В этом разделе описаны все арифметические операции от сравнения до деления, а так же все нюансы при выполнении таких операций. Про этот раздел нельзя сказать вот так, «в двух словах». Скажу лишь, что это настоящая морока и передо мной встала задача понять, как это происходит.
Опишу вкратце свой алгоритм работы «Деление в формате с плавающей точкой». После того, как мы получили операнды А и В, нужно было проверить их на все возможные случаи возникновения исключительных ситуаций. Это и деление на ноль и Nan и бесконечность. Немного ниже, на таблице, изображены типы представления чисел, которые поддерживает формат:

image

Если операнды действительно являлись числами в формате IEEE-754, начинался второй этап выполнения операции: приведение порядков. Ни для кого не секрет, что числа в формате с плавающей точкой выглядят примерно так:

image

Это представление числа в формате с одинарной точностью.
Порядок числа в ЦВМ – это, в моём понимании, порядковый номер числа в ЦВМ, то есть его порядок. Наверняка есть научное определение, но оно лишь запутает ещё больше. Так вот, раз числа имеют разные порядки, их нельзя делить. Следует сначала привести порядки к одному виду смещением порядков. Но для этого требовалось проанализировать порядки на min и маx значение. А когда происходит смещение порядков, мантиссы тоже сдвигаются. Если порядки уравнены, нужно проверить мантиссы, не вылетели ли они за границы и не заполнились ли они нулями и т.д. Закончив ряд проверок, можно приступать к самому главному: наконец-то делить мантиссы. Ну, тут всё просто, как и вся двоичная арифметика. Я делил делитель на делимое, а остаток записывал в регистр и складывал. Там ещё есть несколько способов деления: с восстановление и без восстановления остатка. Да и это ещё не всё! В конце следовало округлить полученный результат по нужному условию и определить знак частного.

Это всего лишь на словах, хоть и звучит страшно, на деле выглядит куда лучше. Тогда я откровенно запал на этот стандарт, что принесло мне не только более глубокие знания в ЦВМ и двоичной арифметике, но и удовольствие что я смог это сделать, удовольствие осознавать то, что я знаю что-то очень важное.
У меня всё, на самом деле тема очень интересная и увлекательная. Кто заинтересовался, с удовольствием скину стандарт IEEE-754 и отвечу на ваши вопросы.

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

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

    +7
    Некоторое время назад на хабре была хорошая статья про арифметику с плавающей точкой, интересующимся советую.
      0
      спасибо огромное, действительно отличная статья
    • НЛО прилетело и опубликовало эту надпись здесь
        0
        с удовольствием отвечу:
        во-первых, этот формат сложен к восприятию и информации о нём действительно мало(к примеру русскую версию стандарта дал нам преподаватель и даже гугл тут не помог найти); во-вторых, хоть точность стандарта и велика, она всё равно не достаточна в нашем нереально развивающемся мире; в третьих, в стандарте очень много воды(только моё мнение) и было бы легче представлять действительные числа в формате с фиксированной точностью ибо так было бы удобнее, но увы.
          +2
          Поделитесь пожалуйста русской версией стандарта. Спасибо.
        +1
        Расскажите про то, какие возможности для упрощения отладки вычислений есть в IEEE 754 (например, SNaN, как заставить процессоры различных архитектур их генерировать вместо NaN).
          0
          сигнализирующее NaN может отличаться от простого например старшим битом мантиссы. Тогда следует учесть ситуацию с этим битом посредством написания некоего условия независимо от архитектуры. Это конечно довольно общее решение, но копать надо в эту сторону.
            +1
            альтернативное представление стандарта, с улыбкой
            www.yur.ru/science/computer/IEEE754.htm
              0
              > А ведь это грубо, говоря дробная часть любого числа, только точность надо знать.

              Grammarnazi повесился.

                0
                если в двух словах, вы правы
                  +1
                  > Я делил делитель на делимое, а остаток записывал в регистр и слаживал.

                  Извиняюсь, но читать такое не приятно и сразу возникает сомнение можно ли доверять автору.
                    +1
                    Извините, всё мы развиваемся. Учту ваши советы в будущем
                      0
                      Я бы тоже не доверял людям, которые не знают правил правописания «не» с наречиями и — расстановки запятых в сложных предложениях.
                    +3
                    > Порядок числа в ЦВМ – это, в моём понимании, порядковый номер числа в ЦВМ, то есть его порядок.

                    Порядок числа — это всего-навсего значение экспоненты.
                      0
                      Кэп рыдает горючими слезами.
                      0
                      а экспонента это что? Не 2 в степени ли? Не порядком ли принято называть?
                        0
                        прошу прощения за сатиру, то порядок-это «два в степени n», то есть представление для удобного восприятия
                          0
                          вы можете отвечать на комментарии непосредственно их авторам. Для этого под каждым комментарием есть маленькая ссылочка «ответить»
                          0
                          Узнаю себя в жажде познания

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

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