- •6. Арифметические операции над числами с плавающей точкой
- •6.1 Операции пересылки или копирования
- •6.1.1 Преобразования формата с плавающей точкой
- •6.1.2 Округление числа с плавающей точкой до целочисленного значения
- •6.1.3 Преобразования между форматами с плавающей точкой и целочисленным форматом
- •6.2 Операции сравнения
6.1.2 Округление числа с плавающей точкой до целочисленного значения
Пусть дано десятичное число в формате с плавающей точкой 7. После округления до целого в режиме округления до ближайшего числа получим 762. После округления числа с плавающей точкой до целочисленного значения в том же режиме округления получим 7,62000102.
При выполнении операции формат результата совпадает с форматом операнда. Знак результата должен совпадать со знаком операнда независимо от значения операнда. В базовых форматах стандарта IEEE 754 коды , 0, простого NaN и числа со смещенным порядком , где – длина поля дробной части мантиссы, копируют в формат результата без преобразования, так как последние имеют порядок и являются целыми числами.
При и мантиссу числа округляют в заданном режиме округления до старших разрядов, включая разряд целого. Отбрасываемые разряды заменяются нулями. Если после округления мантисса переполнена, то выполняют ее нормализацию на 1 разряд вправо и смещенный порядок увеличивают на 1, причем переполнения порядка произойти не может, так как порядок мал. Исключительная ситуация потери точности возникает, если отбрасываемые разряды мантиссы не равны 0.
При порядок и модуль числа меньше 1, но не меньше . В режиме округления до ближайшего числа, если модуль числа равен (дробная часть мантиссы равна 0), число заменяют нулем со знаком операнда. Для этого в поле смещенного порядка записывают код нуля. Если дробная часть мантиссы не равна нулю, число заменяют единицей со знаком операнда. Для этого в поле смещенного порядка записывают код bias, а в поле дробной части мантиссы – код нуля. В других режимах округления правила замещения те же, что и при .
При порядок и модуль числа меньше независимо от того нормализованное оно или нет. Поэтому для получения кода результата код операнда заменяют в режиме округления
до нуля или до ближайшего числа кодом 0 со знаком операнда;
до + отрицательного числа кодом (–0), а положительного – кодом (+1);
до – положительного числа кодом (+0), а отрицательного – кодом (– 1).
Когда , складывается исключительная ситуация потери точности.
6.1.3 Преобразования между форматами с плавающей точкой и целочисленным форматом
Знак результата должен быть равен знаку операнда. Если операнд равен 0, то в формат результата записывают код нуля.
Преобразования из формата с плавающей точкой в целочисленный формат.
Рассмотрим преобразование из базового формата стандарта IEEE 754 в целочисленный формат с фиксированной точкой рис.3-3a.
Если операнд содержит код NaN и целочисленный формат не позволяет представить в нем эти значения, то возникает исключительная ситуация невыполнимая операция (раздел 5.5).
Стандарт рекомендует приводить число в формате с плавающей точкой к целому числу округлением до целочисленного значения, как описано в разделе 6.1.2. Если при округлении до целочисленного значения сложилась исключительная ситуация потери точности (раздел 6.1.2), то следует установить признак потери точности в 1 и выдать сигнал прерывания. Если в полученном промежуточном результате , в целочисленный формат следует записать код нуля. Если , то промежуточный результат нормализованное целое число с порядком равное 1 (дробная часть мантиссы содержит нули). При , где , в формате нормализованное целое число с порядком . Старшие разряды мантиссы значащие. При все разряды мантиссы значащие. При к значащим разрядам мантиссы, размещенным в формате, приписаны нулей справа. Из сказанного следует, что при в целочисленный формат с фиксированной точкой следует копировать знак и значащих разрядов мантиссы промежуточного результата. При этом может сложиться исключительная ситуация переполнения, если длина поля значащих разрядов в формате с фиксированной точкой меньше .
Например, если в формате одинарной точности после округления до целочисленного значения записан код
,
то в целочисленный формат длиной 16 бит следует записать
0|0000 0000 0000 1010
копируя в его младшие биты 1 целого и 3 старших разряда дробной части мантиссы. Разумеется, что в случае представления числа в формате с фиксированной точкой в дополнительном коде, следует выполнить преобразование прямого кода в дополнительный. Если прямой код 0 получен со знаком минус, произойдет изменение знака. Это следует учитывать при программировании.
Однако, если в примере порядок будет не +3, а +16 или большим, то сложится ситуация переполнения формата целого. При переполнении целочисленного формата следует установить признак переполнения в 1 и выдать сигнал прерывания. Последующие действия описаны в разделе 5.5. Если обработка переполнения не выполняется (сигнал прерывания по переполнению блокирован), то следует установить в 1 признак ситуации невыполнимая операция и выдать сигнал прерывания.
Преобразования из целочисленного формата в формат с плавающей точкой.
Если операнд представлен в целочисленном формате с фиксированной точкой и содержит код не числа (например, признак неопределенного значения переменной или код ), то следует установить признак ситуации невыполнимая операция в 1 и выдать сигнал прерывания. Если обработка переполнения не выполняется (сигнал прерывания блокирован), то в формат результата следует записать простое NaN предусмотренное на этот случай.
Если операнд является числом и длина поля целого не больше длины мантиссы в формате результата, то при выполнении преобразования исключительные ситуации не возникают. Если длина поля целого больше длины мантиссы в формате результата, возможна потеря точности.
Если операнд равен 0, то в формат с плавающей точкой следует записать код 0 со знаком операнда.
Если операнд не равный 0 в дополнительном коде, следует преобразовать его в прямой код.
При преобразовании прямого кода целого не равного нулю можно исходить из того, что в поле целого операнда якобы представлена мантисса с запятой размещенной после старшего разряда целого, а порядок задан по умолчанию. Здесь – длина формата операнда.
Если старший разряд целого 1, мантисса нормализована. Иначе – не нормализована. Поэтому при преобразовании можно копировать знак целого в разряд знака формата с плавающей точкой, записывать в поле смещенного порядка константу и считать, что мантисса записана в формате целого. Если мантисса не нормализована, ее следует нормализовать влево в формате целого, уменьшая соответственно смещенный порядок в формате с плавающей точкой.
Если поле дробной части мантиссы в формате с плавающей точкой не меньше , можно дробную часть нормализованной мантиссы копировать в формат с плавающей точкой, дополняя ее нулями справа, при необходимости.
Если в формате с плавающей точкой поле дробной части мантиссы меньше , нормализованную мантиссу следует округлить в заданном режиме округления и ее дробную часть копировать в поле дробной части мантиссы формата с плавающей точкой.
Следует учитывать, что при округлении мантисса может переполниться. Это потребует нормализацию мантиссы вправо и увеличение смещенного порядка на 1. Однако сдвиг мантиссы вправо не изменит значение сохраняемых разрядов содержащих нули. Поэтому при переполнении мантиссы достаточно увеличить смещенный порядок на 1 и копировать из формата целого в дробную часть формата с плавающей точкой сохраняемые разряды мантиссы кроме старшего.
Если отбрасываемые при округлении разряды не равны 0, возникает ситуация потери точности.
Пример 6-1. Пусть операнд представлен в прямом коде в формате целого длиной бит 0|100 0000 0000 0001 (+16 385). Преобразуем его в формат одинарной точности стандарта IEEE 754. Скопируем бит знака операнда в поле знака формата результата, примем смещенный порядок . Так как старший разряд целого в формате операнда 1, то выполнять нормализацию не следует. Скопируем содержимое поля целого операнда без его старшего бита в старшие биты поля дробной части мантиссы формата результата, приписав справа 9 нулей для заполнения формата. Получим
0 | 1000 1101 | 0000 0000 0000 0100 0000 000
Пусть операнд равен 1|000 0000 0001 0000 (–16). Смещенный порядок в формате результата . Так как старший разряд целого в формате операнда 0, то выполним нормализацию, сдвинув код целого на 10 разрядов влево и уменьшим смещенный порядок в формате результата на 10. Получим
1|100 0000 0000 0000 и 1000 0011
После копирования содержимого поля целого без его старшего бита в старшие биты поля дробной части мантиссы формата результата и приписывания справа 9 нулей для заполнения формата, получим
1| 1000 0011 | 0000 0000 0000 0000 0000 000
Пусть операнд представлен в прямом коде в формате целого длиной бит 0|7FFFFF8116 . Преобразуем его в формат одинарной точности стандарта IEEE 754 в режиме округления до ближайшего числа.
Скопируем бит знака операнда в поле знака формата результата, примем смещенный порядок . Мантисса в формате целого нормализованная. Отбрасываемые при округлении разряды мантиссы не равны 0. Поэтому возникает исключительная ситуация потери точности. При блокировании прерывания округлим мантиссу до точности формата, отбрасывая лишние 8 разрядов. Так как отбрасываемые разряды содержат код 1000 0001, то в режиме округления до ближайшего числа следует сохраняемые разряды увеличить на 1. Это приведет к переполнению мантиссы, и все сохраняемые разряды будут равны 0. Поэтому смещенный порядок увеличим на 1 и в дробную часть формата с плавающей точкой скопируем сохраняемые разряды кроме старшего. Получим
0|1001 1110 | 0000 0000 0000 0000 0000 000
Результат отличается от значения операнда из-за округления.
Стандарт IEEE 754 не определяет поведение системы в ситуациях, складывающихся при преобразовании из целочисленного формата в формат с плавающей точкой с длиной мантиссы меньшей, чем длина поля целого в формате с фиксированной точкой. Например, при преобразовании целого в формате слова (32 бита) в формат с одинарной точностью (длина мантиссы 24 бита). Поэтому не следует в программах применять подобные преобразования.