Войти
ПрограммированиеСтатьиОбщее

Детали плавающей точки (2 стр)

Автор:

Стандарт 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-значной мантиссой):

  • 1 бит знака (S)
  • w=k-p бит (смещённой) экспоненты (E)
  • t=p-1 хвостовых бит мантиссы (T)
  • Битыk−1k−2p−1p−20
    ЗначенияS1  E1  .....Ew  T1  .......Tp−1

    Биты экспоненты интерпретируются как беззнаковое целое число, из которого затем вычитается смещение (англ. bias), чтобы дать возможность представлять отрицательные экспоненты.

    Для нормализованных чисел старший бит мантиссы всегда равен 1 и явно не хранится.
    Для того, чтобы иметь возможность представить 0, минимальное значение экспоненты (0) зарезервировано, и означает ту же экспоненту, что и следующее значение (1), но с 0 ведущим битом, который тоже явно не хранится. Числа такого вида в стандарте IEEE 754 называются субнормальными (англ. subnormal numbers, subnormals). Среди программистов более распространено название "денормализованные" (англ. denormalized numbers, denormls).
    Таким образом:

  • Для нормальных чисел: \(\mathrm{value}=(-1)^S \cdot 1.T_1 T_2 \dots T_{p-1} \cdot 2^{E_1 E_2 \dots E_w - \mathrm{bias}}\)
  • Для субнормальных чисел: \(\mathrm{value}=(-1)^S \cdot 0.T_1 T_2 \dots T_{p-1} \cdot 2^{1 - \mathrm{bias}}\)
  • Максимальное значение экспоненты зарезервировано для обозначения бесконечностей (\(+ \infty, \, - \infty\)) - для значений, превышающих все представимые конечные числа, и NaN (англ. Not-a-Number) - для результатов, не имеющих осмысленного представления в вещественных числах (напр. \(\frac{0}{0}\), \(\ln (-1)\)). Их представления различаются хвостовыми битами мантиссы (для бесконечности - все они нулевые, для NaN - есть хотя бы 1 ненулевой бит).

    Таким образом:

    SETКласс
    011…1TTT…TTNaN
    011…1000…00+∞
    0EE…ETTT…TTnormal numbers
    000…0TTT…TTsubnormal numbers
    000…0000…00+0
    100…0000…00−0
    100…0TTT…TTsubnormal numbers
    1EE…ETTT…TTnormal numbers
    111…1000…00−∞
    111…1TTT…TTNaN

    Представление NaN не уникально. Биты мантиссы NaN в стандарте называются нагрузкой (англ. payload). Они могут быть использованы в отладочных целях.

    Стандарт выделяет 2 вида NaN - тихие (quiet, qNaN) и сигналящие (signaling, sNaN):

  • старший хвостовой бит мантиссы qNaN равен 1.
  • старший хвостовой бит мантиссы sNaN равен 0.
  • Большинство операций с 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 - числа половинной точности (half, half-float)
  • binary32 - числа одинарной точности (single, float)
  • binary64 - числа двойной точности (double)
  • binary128 - числа четверной точности (quadruple)
  • Их параметры приведены в таблице:

    Параметрbinary16binary32binary64binary128binary{k} (k ≥128)
    k, размер в битах163264128multiple of 32
    p, точность в битах112453113k − round(4 × log2 (k)) + 13
    emax, максимальная экспонента e151271023163832(k−p−1)−1
    bias (смещение), E − e15127102316383emax
    бит знака11111
    w, ширина экспоненты в битах581115round(4 × log2 (k)) − 13
    t, хвостовые биты мантиссы102352112k − w − 1

    Здесь round означает округление к ближайшему целому (более точное определение не требуется, т. к. выражения внутри не могут дать результат вида integer+0.5).

    Легко видеть, что для всех приведённых форматов:
    emax=bias=2w−1−1

    Для грубых оценок можно пользоваться следующей таблицей:

    Параметрbinary16binary32binary64binary128
    Максимальное значение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-46·10−8 .. 1.2·10-71.1·10−16 .. 2.3·10-169.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), диапазон и точность которых задаются пользователем.

    Страницы: 1 2 3 4 5 6 7 Следующая »

    #floating point, #математика

    4 мая 2017 (Обновление: 31 дек 2018)

    Комментарии [23]