Десятичное число с плавающей запятой - Decimal floating point

Десятичная арифметика с плавающей запятой ( DFP ) относится как к представлению, так и к операциям с десятичными числами с плавающей запятой . Непосредственная работа с десятичными дробями (с основанием 10) позволяет избежать ошибок округления, которые обычно возникают при преобразовании десятичных дробей (часто встречающихся в данных, вводимых человеком, таких как измерения или финансовая информация), в двоичные (с основанием 2) дроби.

Преимущество десятичного представления с плавающей запятой перед десятичным представлением с фиксированной запятой и целочисленным представлением состоит в том, что оно поддерживает гораздо более широкий диапазон значений. Например, в то время как представление с фиксированной точкой, которое выделяет 8 десятичных цифр и 2 десятичных разряда, может представлять числа 123456.78, 8765.43, 123.00 и т. Д., Представление с плавающей запятой с 8 десятичными цифрами может также представлять 1.2345678, 1234567.8, 0.000012345678, 12345678000000000 и т. Д. Этот более широкий диапазон может значительно замедлить накопление ошибок округления во время последовательных вычислений; например, алгоритм суммирования Кахана может использоваться с плавающей запятой для сложения многих чисел без асимптотического накопления ошибки округления.

Реализации

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

В 1953 году компьютер IBM 650 поддерживал 8-разрядный десятичный формат с плавающей запятой. В 1977 году машина Wang VS поддерживала 64-разрядный десятичный формат с плавающей запятой. Библиотека поддержки операций с плавающей запятой для процессора Motorola 68040 обеспечивала 96 -разрядный формат. -битный десятичный формат хранения с плавающей запятой в 1990 году.

Некоторые компьютерные языки имеют реализации десятичной арифметики с плавающей запятой, включая PL / I , C # , Java с большим десятичным числом, emacs с calc и десятичный модуль Python . В 1987 году IEEE выпустил IEEE 854 , стандарт для вычислений с десятичной плавающей запятой, в котором отсутствовала спецификация того, как данные с плавающей запятой должны кодироваться для обмена с другими системами. Впоследствии это было рассмотрено в IEEE 754-2008 , который стандартизировал кодирование десятичных данных с плавающей запятой, хотя и с двумя разными альтернативными методами.

Процессоры IBM POWER6 и более новые POWER включают аппаратную часть DFP, как и IBM System z9 (и более поздние машины zSeries). SilMinds предлагает SilAx, настраиваемый векторный сопроцессор DFP . IEEE 754-2008 определяет это более подробно. Fujitsu также имеет 64-разрядные процессоры Sparc с аппаратным обеспечением DFP.

Microsoft C # или .NET использует System.Decimal.

Кодировка IEEE 754-2008

Стандарт IEEE 754-2008 определяет 32-, 64- и 128-битные десятичные представления с плавающей запятой. Как и в двоичных форматах с плавающей запятой, число делится на знак, показатель степени и значение . В отличие от двоичных чисел с плавающей запятой, числа не обязательно нормализованы; значения с несколькими значащими цифрами имеют несколько возможных представлений: 1 × 10 2 = 0,1 × 10 3 = 0,01 × 10 4 и т. д. Когда мантисса равна нулю, показатель степени может быть любым значением.

Десятичные форматы с плавающей запятой IEEE 754-2008
десятичный32 десятичный64 десятичный128 десятичный (32 k ) Формат
1 1 1 1 Поле знака (биты)
5 5 5 5 Комбинированное поле (биты)
6 8 12 ш = 2 × к + 4 Поле продолжения экспоненты (биты)
20 50 110 т = 30 × к −10 Поле продолжения коэффициента (биты)
32 64 128 32 × к Общий размер (бит)
7 16 34 p = 3 × t / 10 + 1 = 9 × k −2 Размер коэффициента (десятичные цифры)
192 768 12288 3 × 2 ш = 48 × 4 к Диапазон экспоненты
96 384 6144 Emax = 3 × 2 Вт −1 Максимальное значение 9,99 ... × 10 Emax
−95 −383 −6143 Emin = 1 − Emax Наименьшее нормализованное значение 1,00 ... × 10 Emin.
−101 −398 −6176 Этины = 2 − p − Emax Наименьшее ненулевое значение - 1 × 10 этины.

Диапазоны экспоненты были выбраны таким образом, чтобы диапазон, доступный для нормализованных значений, был приблизительно симметричным. Поскольку это не может быть сделано точно с четным числом возможных значений экспоненты, дополнительное значение было присвоено Emax.

Определены два разных представления:

  • Один с двоичным целым полем мантиссы кодирует мантиссу как большое двоичное целое число от 0 до 10 p -1. Ожидается, что это будет более удобно для программных реализаций с использованием двоичного ALU .
  • Другой вариант с плотно упакованным десятичным полем значащего более точно кодирует десятичные цифры. Это ускоряет преобразование в двоичную форму с плавающей запятой и обратно, но требует специального оборудования для эффективного управления. Ожидается, что это будет более удобно для аппаратных реализаций.

Обе альтернативы обеспечивают точно такой же диапазон представляемых значений.

Два старших бита экспоненты ограничены диапазоном 0–2, а 4 старших разряда мантиссы ограничены диапазоном 0-9. 30 возможных комбинаций закодированы в 5-битном поле вместе со специальными формами для бесконечности и NaN .

Если старшие 4 бита мантиссы находятся между 0 и 7, закодированное значение начинается следующим образом:

s 00mmm xxx   Exponent begins with 00, significand with 0mmm
s 01mmm xxx   Exponent begins with 01, significand with 0mmm
s 10mmm xxx   Exponent begins with 10, significand with 0mmm

Если первые 4 бита мантиссы представляют собой двоичные 1000 или 1001 (десятичные 8 или 9), число начинается следующим образом:

s 1100m xxx   Exponent begins with 00, significand with 100m
s 1101m xxx   Exponent begins with 01, significand with 100m
s 1110m xxx   Exponent begins with 10, significand with 100m

Ведущий бит (s в приведенном выше) является битом знака, а следующие биты (xxx в приведенном выше) кодируют биты дополнительной экспоненты и оставшуюся часть наиболее значимой цифры, но детали меняются в зависимости от используемой альтернативы кодирования.

Окончательные комбинации используются для бесконечностей и NaN и одинаковы для обеих альтернативных кодировок:

s 11110 x   ±Infinity (see Extended real number line)
s 11111 0   quiet NaN (sign bit ignored)
s 11111 1   signaling NaN (sign bit ignored)

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

Двоичное целочисленное значащее поле

В этом формате используется двоичное значение от 0 до 10 p -1. Например, значение Decimal32 может быть до 10 7 -1 = 9 999 999 = 98967F 16 = 1001 1000100101 1001111111 2 . Хотя кодирование может представлять большие значения, они недопустимы, и стандарт требует, чтобы реализации трактовали их как 0, если они встречаются на входе.

Как описано выше, кодирование варьируется в зависимости от того, находятся ли 4 старших бита значения в диапазоне от 0 до 7 (от 0000 2 до 0111 2 ) или выше (1000 2 или 1001 2 ).

Если 2 бита после бита знака равны «00», «01» или «10», то поле экспоненты состоит из 8 бит, следующих за битом знака (упомянутые 2 бита плюс 6 бит «поля продолжения экспоненты»). , а мантисса - это оставшиеся 23 бита с неявным начальным 0-битом, показанные здесь в круглых скобках:

 s 00eeeeee   (0)ttt tttttttttt tttttttttt
 s 01eeeeee   (0)ttt tttttttttt tttttttttt
 s 10eeeeee   (0)ttt tttttttttt tttttttttt

Сюда входят субнормальные числа, у которых ведущая цифра мантиссы равна 0.

Если 2 бита после знакового бита равны «11», то 8-битное поле экспоненты сдвигается на 2 бита вправо (после как знакового бита, так и «11» битов после этого), и представленное значение находится в оставшейся части. 21 бит. В этом случае есть неявная (то есть не сохраненная) ведущая 3-битная последовательность "100" в истинном значении:

 s 1100eeeeee (100)t tttttttttt tttttttttt
 s 1101eeeeee (100)t tttttttttt tttttttttt
 s 1110eeeeee (100)t tttttttttt tttttttttt

2-битная последовательность «11» после знакового бита указывает на то, что существует неявный 3-битный префикс «100» к значимой величине.

Обратите внимание, что ведущие биты поля мантиссы не кодируют наиболее значимую десятичную цифру; они просто являются частью большего чисто двоичного числа. Например, значение 8 000 000 кодируется как двоичное значение 0111 1010000100 1000000000 , при этом ведущие 4 бита кодируют 7; первая мантисса, которая требует 24-го бита (и, следовательно, вторая форма кодирования), равна 2 23 = 8 388 608 .

В приведенных выше случаях представлено значение:

(−1) знак × 10 показатель степени − 101 × значение

Decimal64 и Decimal128 работают аналогично, но с полями продолжения экспоненты и значения больше. Для Decimal128 вторая форма кодирования фактически никогда не используется; наибольшее допустимое значение 10 34 -1 = 1ED09BEAD87C0378D8E63FFFFFFFF 16 может быть представлено 113 битами.

Плотно упакованное десятичное значащее поле

В этой версии мантисса хранится как последовательность десятичных цифр. Первая цифра находится между 0 и 9 (3 или 4 двоичных разряда), а остальная часть мантиссы использует плотно упакованное десятичное (DPD) кодирование.

Первые 2 бита экспоненты и первая цифра (3 или 4 бита) мантиссы объединяются в пять битов, следующих за битом знака. За ним следует поле продолжения экспоненты с фиксированным смещением.

Наконец, поле продолжения мантиссы состоит из 2, 5 или 11 10-битных деклетов , каждое из которых кодирует 3 десятичные цифры.

Если первые два бита после знакового бита равны «00», «01» или «10», то это ведущие биты экспоненты, а три бита после них интерпретируются как ведущая десятичная цифра (от 0 до 7 ):

    Comb.  Exponent          Significand
 s 00 TTT (00)eeeeee (0TTT)[tttttttttt][tttttttttt]
 s 01 TTT (01)eeeeee (0TTT)[tttttttttt][tttttttttt]
 s 10 TTT (10)eeeeee (0TTT)[tttttttttt][tttttttttt]

Если первые два бита после знакового бита равны «11», то вторые два бита являются ведущими битами экспоненты, а последний бит имеет префикс «100», чтобы сформировать ведущую десятичную цифру (8 или 9):

    Comb.  Exponent          Significand
 s 1100 T (00)eeeeee (100T)[tttttttttt][tttttttttt]
 s 1101 T (01)eeeeee (100T)[tttttttttt][tttttttttt]
 s 1110 T (10)eeeeee (100T)[tttttttttt][tttttttttt]

Оставшиеся две комбинации (11110 и 11111) 5-битного поля используются для представления ± бесконечность и NaN соответственно.

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

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

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

Добавление

Простой способ сложить числа с плавающей запятой - сначала представить их с одинаковым показателем степени. В приведенном ниже примере второе число сдвинуто вправо на 3 цифры. Действуем обычным способом сложения:

Следующий пример является десятичным, что означает просто основание 10.

  123456.7 = 1.234567 × 105
  101.7654 = 1.017654 × 102 = 0.001017654 × 105

Следовательно:

  123456.7 + 101.7654 = (1.234567 × 105) + (1.017654 × 102)
                      = (1.234567 × 105) + (0.001017654 × 105)
                      = 105 × (1.234567 + 0.001017654)
                      = 105 × 1.235584654

Это не что иное, как преобразование в научную нотацию . В деталях:

  e=5;  s=1.234567     (123456.7)
+ e=2;  s=1.017654     (101.7654)
  e=5;  s=1.234567
+ e=5;  s=0.001017654  (after shifting)
--------------------
  e=5;  s=1.235584654  (true sum: 123558.4654)

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

  e=5;  s=1.235585    (final sum: 123558.5)

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

  e=5;  s=1.234567
+ e=−3; s=9.876543
  e=5;  s=1.234567
+ e=5;  s=0.00000009876543 (after shifting)
----------------------
  e=5;  s=1.23456709876543 (true sum)
  e=5;  s=1.234567         (after rounding/normalization)

Другая проблема потери значимости возникает, когда вычитаются два близких числа. е = 5; s = 1,234571 и e = 5; s = 1,234567 представляют собой рациональные числа 123457.1467 и 123456.659.

  e=5;  s=1.234571
− e=5;  s=1.234567
----------------
  e=5;  s=0.000004
  e=−1; s=4.000000 (after rounding/normalization)

Лучшее представление этой разницы - e = −1; s = 4.877000, что более чем на 20% отличается от e = −1; s = 4,000000. В крайних случаях конечный результат может быть нулевым, даже если точный расчет может составлять несколько миллионов. Эта отмена иллюстрирует опасность предположения, что все цифры вычисляемого результата значимы.

Работа с последствиями этих ошибок - тема численного анализа .

Умножение

Для умножения значения умножаются, экспоненты складываются, а результат округляется и нормализуется.

  e=3;  s=4.734612
× e=5;  s=5.417242
-----------------------
  e=8;  s=25.648538980104 (true product)
  e=8;  s=25.64854        (after rounding)
  e=9;  s=2.564854        (after normalization)

Деление производится аналогично, но более сложно.

При умножении или делении нет проблем с отменой или поглощением, хотя небольшие ошибки могут накапливаться при многократном выполнении операций. На практике способ выполнения этих операций в цифровой логике может быть довольно сложным.

Смотрите также

использованная литература

дальнейшее чтение