Детали плавающей точки (2 стр)
Автор: FordPerfect
Стандарт IEEE 754
Текущая ревизия стандарта: IEEE 754-2008 (этому стандарту идентичен по содержанию ISO/IEC/IEEE 60559:2011), пришедшая на смену IEEE 754-1985. Кроме двоичных чисел с плавающей точкой, стандарт определяет также десятичные, которые в данной статье не рассматриваются. Можно отметить, что Кэхэн агитировал за широкое применение десятичных чисел с плавающей точкой, как более WYSIWYG для большинства пользователей.
Официальный текст стандарта распространяется на платной основе, но копии текста могут быть легко найдены интуитивным запросом к google.
Документ относительно небольшой (70 стр.) и достаточно легко читается.
Предмет стандарта
Вопрос "что является предметом стандарта?" стоит оговорить явно, т. к. ответ может быть несколько неожиданным.
В основном, стандарт посвящён 2 вопросам:
1. Описание нескольких форматов представления чисел с плавающей точкой.
2. Определение семантики некоторого набора операций.
Какие из операций реализуются "в железе", а какие - программно, стандарт не оговаривает.
Например, операцию сложения типично реализует процессор, а приведение числа к текстовому виду (одна из операций, семантика которой определена стандартом) - скорее относится к компетенции функции printf стандартной библиотеки.
Формат представления
Стандарт различает interchange formats (форматы обмена данными), для которых определено конкретное битовое представление, и arithmetic formats (арифметические форматы), для которых определена семантика операций, но требования к конкретному представлению менее чёткие.
Interchange formats могут быть использованы в качестве арифметических.
Экспоненциальная запись
Формат основан на экспоненциальной записи, знакомой большинству программистов:
\(\pm M \cdot B^{E}\)
здесь:
\(B\) (основание, англ. base, также называемое radix) - целое число, \(B \geq 2\),
\(E\) (показатель степени (экспонента), англ. exponent) - целое число,
\(M\) (мантисса, англ. mantissa) - \(B\)-ичная дробь.
Например:
\(123.45 \cdot 10^{3}\)
Число может быть записано не единственным образом: сменой экспоненты точка в мантиссе может быть произвольно перемещена (отсюда и происходит название "плавающая точка").
Например то же число может быть записано в виде:
\(1.2345 \cdot 10^{5}\)
Такую запись (перед точкой следует ровно 1 ненулевой знак, другими словами \(1 \leq \left| M \right| < B\)) называют нормализованной.
Легко видеть, что для 0 нормализованная запись отсутствует.
Для двоичной нормализованной записи первая цифра мантиссы - всегда 1 (т. к. других ненулевых цифр в двоичной системе нет).
Например, то же число в двоичной экспоненциальной записи:
\(1.1110001000111010_2 \cdot 2^{17}\). Здесь основание и экспонента записаны в десятичной системе. Полностью в двоичной системе:
\(1.1110001000111010_2 \cdot 10_2^{10001_2}\)
Представление чисел с плавающей точкой
Общая структура k-битных interchange formats (с p-значной мантиссой):
| Биты | k−1 | k−2 | p−1 | p−2 | 0 | ||
| Значения | S1 | E1 | ..... | Ew | T1 | ....... | Tp−1 |
Биты экспоненты интерпретируются как беззнаковое целое число, из которого затем вычитается смещение (англ. bias), чтобы дать возможность представлять отрицательные экспоненты.
Для нормализованных чисел старший бит мантиссы всегда равен 1 и явно не хранится.
Для того, чтобы иметь возможность представить 0, минимальное значение экспоненты (0) зарезервировано, и означает ту же экспоненту, что и следующее значение (1), но с 0 ведущим битом, который тоже явно не хранится. Числа такого вида в стандарте IEEE 754 называются субнормальными (англ. subnormal numbers, subnormals). Среди программистов более распространено название "денормализованные" (англ. denormalized numbers, denormls).
Таким образом:
Максимальное значение экспоненты зарезервировано для обозначения бесконечностей (\(+ \infty, \, - \infty\)) - для значений, превышающих все представимые конечные числа, и NaN (англ. Not-a-Number) - для результатов, не имеющих осмысленного представления в вещественных числах (напр. \(\frac{0}{0}\), \(\ln (-1)\)). Их представления различаются хвостовыми битами мантиссы (для бесконечности - все они нулевые, для NaN - есть хотя бы 1 ненулевой бит).
Таким образом:
| S | E | T | Класс |
| 0 | 11…1 | TTT…TT | NaN |
| 0 | 11…1 | 000…00 | +∞ |
| 0 | EE…E | TTT…TT | normal numbers |
| 0 | 00…0 | TTT…TT | subnormal numbers |
| 0 | 00…0 | 000…00 | +0 |
| 1 | 00…0 | 000…00 | −0 |
| 1 | 00…0 | TTT…TT | subnormal numbers |
| 1 | EE…E | TTT…TT | normal numbers |
| 1 | 11…1 | 000…00 | −∞ |
| 1 | 11…1 | TTT…TT | NaN |
Представление NaN не уникально. Биты мантиссы NaN в стандарте называются нагрузкой (англ. payload). Они могут быть использованы в отладочных целях.
Стандарт выделяет 2 вида NaN - тихие (quiet, qNaN) и сигналящие (signaling, sNaN):
Большинство операций с sNaN, согласно стандарту, по умолчанию генерируют исключение, в отличие от операций с qNaN. Стандарт не оговаривает цели, с которыми применяется sNaN, но приводит в качестве примера представление неинициализированных переменных.
Можно явным образом сделать несколько наблюдений:
Наблюдение 0: все представимые конечные числа обозначают вполне конкретные вещественные числа. Утверждения вида "вещественные числа - неточные, и обозначают некоторый диапазон значений" могут быть справедливы для конкретной задачи, но не являются, в общем случае, свойством присущим самим числам с плавающей точкой.
Наблюдение 1: все представимые конечные числа - рациональные и, более того, - конечные десятичные дроби.
Наблюдение 2: все положительные представимые числа (включая бесконечность, но не NaN) - имеют тот же порядок следования, что и целые числа с тем же битовым представлением (предполагая совпадающие endiannes для целых и чисел с плавающей точкой). Для отрицательных чисел - порядок обратный.
Наблюдение 3: существуют положительный и отрицательный нули. Во многих ситуациях они равнозначны, но в их поведении есть различия.
Наблюдение 4: для любого вещественного числа, находящегося между двумя соседним представимыми числами - одно из этих чисел будет оканчиваться (в смысле младшего бита мантиссы) на 0, другое - на 1.
Наблюдение 5: все целые числа в диапазоне −2p .. +2p представимы точно.
Стандартные форматы
Стандарт определяет базовые форматы: binary32, binary64, binary128, а также формат binary16 и общий способ построения binary{k}, для k>=128, кратного 32.
Для них часто используют названия:
Их параметры приведены в таблице:
| Параметр | binary16 | binary32 | binary64 | binary128 | binary{k} (k ≥128) |
| k, размер в битах | 16 | 32 | 64 | 128 | multiple of 32 |
| p, точность в битах | 11 | 24 | 53 | 113 | k − round(4 × log2 (k)) + 13 |
| emax, максимальная экспонента e | 15 | 127 | 1023 | 16383 | 2(k−p−1)−1 |
| bias (смещение), E − e | 15 | 127 | 1023 | 16383 | emax |
| бит знака | 1 | 1 | 1 | 1 | 1 |
| w, ширина экспоненты в битах | 5 | 8 | 11 | 15 | round(4 × log2 (k)) − 13 |
| t, хвостовые биты мантиссы | 10 | 23 | 52 | 112 | k − w − 1 |
Здесь round означает округление к ближайшему целому (более точное определение не требуется, т. к. выражения внутри не могут дать результат вида integer+0.5).
Легко видеть, что для всех приведённых форматов:
emax=bias=2w−1−1
Для грубых оценок можно пользоваться следующей таблицей:
| Параметр | binary16 | binary32 | binary64 | binary128 |
| Максимальное значение | 65535 | ~3.4·10+38 | ~1.8·10+308 | ~1.2·10+4932 |
| Минимальное положительное нормализованное значение | ~6.1·10−5 | ~1.2·10−38 | ~2.2·10−308 | ~3.4·10−4932 |
| Минимальное положительное значение | ~8·10−8 | ~1.4·10−45 | ~4.9·10−324 | ~6.5·10−4966 |
| Относительная ошибка | 4.9·10−4 .. 9.8·10-4 | 6·10−8 .. 1.2·10-7 | 1.1·10−16 .. 2.3·10-16 | 9.7·10−35 .. 2·10-34 |
| Точно представимы все целые в диапазоне | −211 .. +211 (−2048 .. +2048) | −224 .. +224 (−16777216 .. +16777216) | −253 .. +253 | −2113 .. +2113 |
Пример 1. Число 1.375 (равное \(\frac{11}{8}\)) в формате binary32 имеет вид (младшие биты - справа):
00111111101100000000000000000000
Эти биты можно проинтерпретировать как шестнадцатеричное число:
3FB0000016
Пример 2. Число с представлением в binary64 0011111111110000000000000000000000000000000000000000000000000001 (3FF000000000000116) в десятичной записи имеет вид (это точное значение)
1.0000000000000002220446049250313080847263336181640625
и является следующим представимым в binary64 числом, после 1.0.
Расширенные форматы
Стандарт рекомендует (но не требует) реализации предоставлять расширенный формат или форматы (англ. extended precision format), являющийся надмножеством некоторого базового (более конкретно - расширенный тип должен иметь диапазон экспонент следующего по размеру базового типа, и диапазон мантисс между данным и следующим базовыми типами). Конкретное битовое представление такого формата определяется реализацией. Этот формат может быть использован для повышения точности промежуточных вычислений.
Примером extended precision format является 80-битный формат сопроцессора x87 с явным ведущим битом мантиссы, расширяющий тип binary64 (и поэтому называемый double-extended).
Стандарт также упоминает расширяемые форматы (англ. extendable precision format), диапазон и точность которых задаются пользователем.
4 мая 2017 (Обновление: 31 дек 2018)