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

32-битный формат компьютерного числа

Формат чисел с плавающей точкой одинарной точности (иногда называемый FP32 или float32 ) — это компьютерный числовой формат , обычно занимающий 32 бита в памяти компьютера ; он представляет широкий динамический диапазон числовых значений с использованием плавающей запятой .

Переменная с плавающей точкой может представлять более широкий диапазон чисел, чем переменная с фиксированной точкой той же разрядности за счет точности. Знаковая 32-битная целая переменная имеет максимальное значение 2 31 − 1 = 2 147 483 647, тогда как 32-битная переменная с плавающей точкой IEEE 754 с основанием 2 имеет максимальное значение (2 − 2 −23 ) × 2 127 ≈ 3,4028235 × 10 38 . Все целые числа с семью или менее десятичными цифрами и любые 2 n для целого числа −149 ≤ n ≤ 127 могут быть точно преобразованы в значение с плавающей точкой одинарной точности IEEE 754.

В стандарте IEEE 754 32-битный формат с основанием 2 официально называется binary32 ; в IEEE 754-1985 он назывался single . IEEE 754 определяет дополнительные типы с плавающей точкой, такие как 64-битные представления с основанием 2 двойной точности и, в последнее время, представления с основанием 10.

Одним из первых языков программирования, предоставляющих типы данных с плавающей точкой одинарной и двойной точности, был Fortran . До широкого принятия IEEE 754-1985 представление и свойства типов данных с плавающей точкой зависели от производителя и модели компьютера, а также от решений, принимаемых разработчиками языков программирования. Например, тип данных с одинарной точностью GW-BASIC представлял собой 32-битный формат с плавающей точкой MBF.

Одинарная точность называется REAL в Fortran ; [1] SINGLE-FLOAT в Common Lisp ; [2] float в C , C++ , C# и Java ; [3] Float в Haskell [4] и Swift ; [5] и Single в Object Pascal ( Delphi ), Visual Basic и MATLAB . Однако float в Python , Ruby , PHP и OCaml и single в версиях Octave до 3.2 относятся к числам с двойной точностью . В большинстве реализаций PostScript и некоторых встроенных системах единственной поддерживаемой точностью является single.

Стандарт IEEE 754: двоичный32

Стандарт IEEE 754 определяет binary32 как имеющий:

Это дает точность от 6 до 9 значащих десятичных цифр . Если десятичная строка с максимум 6 значащими цифрами преобразуется в формат одинарной точности IEEE 754, давая обычное число , а затем преобразуется обратно в десятичную строку с тем же количеством цифр, конечный результат должен соответствовать исходной строке. Если число одинарной точности IEEE 754 преобразуется в десятичную строку с минимум 9 значащими цифрами, а затем преобразуется обратно в представление одинарной точности, конечный результат должен соответствовать исходному числу. [6]

Бит знака определяет знак числа, который также является знаком мантиссы. Поле экспоненты представляет собой 8-битное целое число без знака от 0 до 255 в смещенной форме : значение 127 представляет фактическую экспоненту, равную нулю. Экспоненты находятся в диапазоне от −126 до +127 (таким образом, от 1 до 254 в поле экспоненты), поскольку смещенные значения экспоненты 0 (все нули) и 255 (все единицы) зарезервированы для специальных чисел ( субнормальные числа , нули со знаком , бесконечности и NaN ).

Истинная мантисса обычных чисел включает 23 дробных бита справа от двоичной точки и неявный ведущий бит (слева от двоичной точки) со значением 1. Субнормальные числа и нули (являющиеся числами с плавающей точкой, меньшими по величине, чем наименьшее положительное нормальное число) представлены смещенным значением экспоненты 0, что дает неявному ведущему биту значение 0. Таким образом, в формате памяти появляются только 23 дробных бита мантиссы , но общая точность составляет 24 бита (эквивалентно log 10 (2 24 ) ≈ 7,225 десятичных цифр).

Биты расположены следующим образом:

Действительное значение, принимаемое заданными 32-битными двоичными данными32 с заданным знаком , смещенной экспонентой e (8-битное целое число без знака) и 23-битной дробью , равно

( 1 ) b 31 × 2 ( b 30 b 29 b 23 ) 2 127 × ( 1. b 22 b 21 b 0 ) 2 {\displaystyle (-1)^{b_{31}}\times 2^{(b_{30}b_{29}\dots b_{23})_{2}-127}\times (1.b_{22}b_{21}\dots b_{0})_{2}} ,

что дает

value = ( 1 ) sign × 2 ( E 127 ) × ( 1 + i = 1 23 b 23 i 2 i ) . {\displaystyle {\text{value}}=(-1)^{\text{sign}}\times 2^{(E-127)}\times \left(1+\sum _{i=1}^{23}b_{23-i}2^{-i}\right).}

В этом примере:

  • sign = b 31 = 0 {\displaystyle {\text{sign}}=b_{31}=0} ,
  • ( 1 ) sign = ( 1 ) 0 = + 1 { 1 , + 1 } {\displaystyle (-1)^{\text{sign}}=(-1)^{0}=+1\in \{-1,+1\}} ,
  • E = ( b 30 b 29 b 23 ) 2 = i = 0 7 b 23 + i 2 + i = 124 { 1 , , ( 2 8 1 ) 1 } = { 1 , , 254 } {\displaystyle E=(b_{30}b_{29}\dots b_{23})_{2}=\sum _{i=0}^{7}b_{23+i}2^{+i}=124\in \{1,\ldots ,(2^{8}-1)-1\}=\{1,\ldots ,254\}} ,
  • 2 ( E 127 ) = 2 124 127 = 2 3 { 2 126 , , 2 127 } {\displaystyle 2^{(E-127)}=2^{124-127}=2^{-3}\in \{2^{-126},\ldots ,2^{127}\}} ,
  • 1. b 22 b 21 . . . b 0 = 1 + i = 1 23 b 23 i 2 i = 1 + 1 2 2 = 1.25 { 1 , 1 + 2 23 , , 2 2 23 } [ 1 ; 2 2 23 ] [ 1 ; 2 ) {\displaystyle 1.b_{22}b_{21}...b_{0}=1+\sum _{i=1}^{23}b_{23-i}2^{-i}=1+1\cdot 2^{-2}=1.25\in \{1,1+2^{-23},\ldots ,2-2^{-23}\}\subset [1;2-2^{-23}]\subset [1;2)} .

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

  • value = ( + 1 ) × 2 3 × 1.25 = + 0.15625 {\displaystyle {\text{value}}=(+1)\times 2^{-3}\times 1.25=+0.15625} .

Примечание:

  • 1 + 2 23 1.000 000 119 {\displaystyle 1+2^{-23}\approx 1.000\,000\,119} ,
  • 2 2 23 1.999 999 881 {\displaystyle 2-2^{-23}\approx 1.999\,999\,881} ,
  • 2 126 1.175 494 35 × 10 38 {\displaystyle 2^{-126}\approx 1.175\,494\,35\times 10^{-38}} ,
  • 2 + 127 1.701 411 83 × 10 + 38 {\displaystyle 2^{+127}\approx 1.701\,411\,83\times 10^{+38}} .

Кодирование экспоненты

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

Таким образом, чтобы получить истинную экспоненту, определенную смещением-двоичным представлением, смещение 127 необходимо вычесть из сохраненной экспоненты.

Сохраненные показатели 00 H и FF H интерпретируются особым образом.

Экспонентадробь = 0дробь ≠ 0Уравнение
00 Н = 00000000 2±нольсубнормальное число ( 1 ) sign × 2 126 × 0. fraction {\displaystyle (-1)^{\text{sign}}\times 2^{-126}\times 0.{\text{fraction}}}
01 Н , ..., ФЕ Н = 00000001 2 , ..., 11111110 2нормальное значение ( 1 ) sign × 2 exponent 127 × 1. fraction {\displaystyle (-1)^{\text{sign}}\times 2^{{\text{exponent}}-127}\times 1.{\text{fraction}}}
ФФ Н = 11111111 2± бесконечностьNaN (тихий, сигнальный)

Минимальное положительное нормальное значение равно , а минимальное положительное (субнормальное) значение равно . 2 126 1.18 × 10 38 {\displaystyle 2^{-126}\approx 1.18\times 10^{-38}} 2 149 1.4 × 10 45 {\displaystyle 2^{-149}\approx 1.4\times 10^{-45}}

Преобразование десятичного числа в двоичное32

В общем случае, строгое преобразование (включая округление) действительного числа в эквивалентный ему двоичный формат binary32 можно найти в самом стандарте IEEE 754.

Здесь мы можем показать, как преобразовать действительное число с основанием 10 в двоичный формат IEEE 75432, используя следующую схему:

  • Рассмотрим действительное число с целой и дробной частью, например 12,375.
  • Преобразовать и нормализовать целую часть в двоичную
  • Преобразуйте дробную часть, используя следующую технику, как показано здесь.
  • Сложите два результата и скорректируйте их, чтобы получить правильное окончательное преобразование.

Преобразование дробной части: Рассмотрим 0,375, дробную часть числа 12,375. Чтобы преобразовать его в двоичную дробь, умножьте дробь на 2, возьмите целую часть и повторите с новой дробью на 2, пока не будет найдена дробь, равная нулю, или пока не будет достигнут предел точности, который составляет 23 цифры дроби для формата IEEE 754 binary32.

0.375 × 2 = 0.750 = 0 + 0.750 b 1 = 0 {\displaystyle 0.375\times 2=0.750=0+0.750\Rightarrow b_{-1}=0} , целая часть представляет собой двоичную дробную цифру. Умножьте 0,750 на 2, чтобы продолжить
0.750 × 2 = 1.500 = 1 + 0.500 b 2 = 1 {\displaystyle 0.750\times 2=1.500=1+0.500\Rightarrow b_{-2}=1}
0.500 × 2 = 1.000 = 1 + 0.000 b 3 = 1 {\displaystyle 0.500\times 2=1.000=1+0.000\Rightarrow b_{-3}=1} , дробь = 0,011, завершить

Мы видим, что может быть точно представлено в двоичном виде как . Не все десятичные дроби могут быть представлены в виде конечной двоичной дроби. Например, десятичная дробь 0,1 не может быть представлена ​​в двоичном виде точно, только приблизительно. Поэтому: ( 0.375 ) 10 {\displaystyle (0.375)_{10}} ( 0.011 ) 2 {\displaystyle (0.011)_{2}}

( 12.375 ) 10 = ( 12 ) 10 + ( 0.375 ) 10 = ( 1100 ) 2 + ( 0.011 ) 2 = ( 1100.011 ) 2 {\displaystyle (12.375)_{10}=(12)_{10}+(0.375)_{10}=(1100)_{2}+(0.011)_{2}=(1100.011)_{2}}

Поскольку формат IEEE 754 binary32 требует представления действительных значений в формате (см. Нормализованное число , Денормализованное число ), 1100.011 сдвигается вправо на 3 цифры, чтобы стать ( 1. x 1 x 2 . . . x 23 ) 2 × 2 e {\displaystyle (1.x_{1}x_{2}...x_{23})_{2}\times 2^{e}} ( 1.100011 ) 2 × 2 3 {\displaystyle (1.100011)_{2}\times 2^{3}}

Наконец мы видим, что: ( 12.375 ) 10 = ( 1.100011 ) 2 × 2 3 {\displaystyle (12.375)_{10}=(1.100011)_{2}\times 2^{3}}

Из чего мы делаем вывод:

  • Показатель степени равен 3 (и в смещенной форме он, следовательно, равен ) ( 127 + 3 ) 10 = ( 130 ) 10 = ( 1000   0010 ) 2 {\displaystyle (127+3)_{10}=(130)_{10}=(1000\ 0010)_{2}}
  • Дробь равна 100011 (смотря вправо от двоичной точки)

Из них мы можем сформировать результирующее 32-битное двоичное представление формата IEEE 754 для числа 12,375:

( 12.375 ) 10 = ( 0   10000010   10001100000000000000000 ) 2 = ( 41460000 ) 16 {\displaystyle (12.375)_{10}=(0\ 10000010\ 10001100000000000000000)_{2}=(41460000)_{16}}

Примечание: рассмотрите возможность преобразования 68.123 в формат IEEE 754 binary32: используя описанную выше процедуру, вы ожидаете получить число с последними 4 битами, равными 1001. Однако из-за поведения округления по умолчанию в формате IEEE 754 вы получите число с последними 4 битами, равными 1010. ( 42883EF9 ) 16 {\displaystyle ({\text{42883EF9}})_{16}} ( 42883EFA ) 16 {\displaystyle ({\text{42883EFA}})_{16}}

Пример 1: Рассмотрим десятичную дробь 1. Мы видим, что: ( 1 ) 10 = ( 1.0 ) 2 × 2 0 {\displaystyle (1)_{10}=(1.0)_{2}\times 2^{0}}

Из чего мы делаем вывод:

  • Показатель степени равен 0 (и в смещенной форме он, следовательно, равен ( 127 + 0 ) 10 = ( 127 ) 10 = ( 0111   1111 ) 2 {\displaystyle (127+0)_{10}=(127)_{10}=(0111\ 1111)_{2}}
  • Дробь равна 0 (смотрим вправо от двоичной точки в 1.0 - все ) 0 = 000...0 {\displaystyle 0=000...0}

Из них мы можем сформировать результирующее 32-битное двоичное представление формата IEEE 754 для действительного числа 1:

( 1 ) 10 = ( 0   01111111   00000000000000000000000 ) 2 = ( 3F800000 ) 16 {\displaystyle (1)_{10}=(0\ 01111111\ 00000000000000000000000)_{2}=({\text{3F800000}})_{16}}

Пример 2: Рассмотрим значение 0,25. Мы видим, что: ( 0.25 ) 10 = ( 1.0 ) 2 × 2 2 {\displaystyle (0.25)_{10}=(1.0)_{2}\times 2^{-2}}

Из чего мы делаем вывод:

  • Показатель степени равен −2 (а в смещенной форме он равен ) ( 127 + ( 2 ) ) 10 = ( 125 ) 10 = ( 0111   1101 ) 2 {\displaystyle (127+(-2))_{10}=(125)_{10}=(0111\ 1101)_{2}}
  • Дробь равна 0 (если смотреть вправо от двоичной точки в 1.0, то там все нули)

Из них мы можем сформировать результирующее 32-битное двоичное представление формата IEEE 754 для действительного числа 0,25:

( 0.25 ) 10 = ( 0   01111101   00000000000000000000000 ) 2 = ( 3E800000 ) 16 {\displaystyle (0.25)_{10}=(0\ 01111101\ 00000000000000000000000)_{2}=({\text{3E800000}})_{16}}

Пример 3: Рассмотрим значение 0,375. Мы увидели, что 0.375 = ( 0.011 ) 2 = ( 1.1 ) 2 × 2 2 {\displaystyle 0.375={(0.011)_{2}}={(1.1)_{2}}\times 2^{-2}}

Следовательно, определив представление 0,375, мы можем действовать, как указано выше: ( 1.1 ) 2 × 2 2 {\displaystyle {(1.1)_{2}}\times 2^{-2}}

  • Показатель степени равен −2 (а в смещенной форме он равен ) ( 127 + ( 2 ) ) 10 = ( 125 ) 10 = ( 0111   1101 ) 2 {\displaystyle (127+(-2))_{10}=(125)_{10}=(0111\ 1101)_{2}}
  • Дробь равна 1 (смотря вправо от двоичной точки в 1.1, мы видим единицу ) 1 = x 1 {\displaystyle 1=x_{1}}

Из них мы можем сформировать результирующее 32-битное двоичное представление формата IEEE 754 для действительного числа 0,375:

( 0.375 ) 10 = ( 0   01111101   10000000000000000000000 ) 2 = ( 3EC00000 ) 16 {\displaystyle (0.375)_{10}=(0\ 01111101\ 10000000000000000000000)_{2}=({\text{3EC00000}})_{16}}

Преобразование двоичного32 в десятичное

Если значение binary32, в данном примере 41C80000 , представлено в шестнадцатеричном формате, мы сначала преобразуем его в двоичный формат:

41C8 0000 16 = 0100   0001   1100   1000   0000   0000   0000   0000 2 {\displaystyle {\text{41C8 0000}}_{16}=0100\ 0001\ 1100\ 1000\ 0000\ 0000\ 0000\ 0000_{2}}

затем мы разбиваем его на три части: знаковый бит, показатель степени и мантисса.

  • Знаковый бит: 0 2 {\displaystyle 0_{2}}
  • Показатель степени: 1000   0011 2 = 83 16 = 131 10 {\displaystyle 1000\ 0011_{2}=83_{16}=131_{10}}
  • Значащая часть: 100   1000   0000   0000   0000   0000 2 = 480000 16 {\displaystyle 100\ 1000\ 0000\ 0000\ 0000\ 0000_{2}=480000_{16}}

Затем мы добавляем неявный 24-й бит к значащей части:

  • Значащая часть: 1 100   1000   0000   0000   0000   0000 2 = C80000 16 {\displaystyle \mathbf {1} 100\ 1000\ 0000\ 0000\ 0000\ 0000_{2}={\text{C80000}}_{16}}

и декодируем значение показателя степени, вычитая 127:

  • Исходный показатель степени: 83 16 = 131 10 {\displaystyle 83_{16}=131_{10}}
  • Расшифрованная экспонента: 131 127 = 4 {\displaystyle 131-127=4}

Каждый из 24 битов мантиссы (включая неявный 24-й бит), с 23-го по 0-й бит, представляет собой значение, начинающееся с 1 и уменьшающееся вдвое для каждого бита, как показано ниже:

бит 23 = 1бит 22 = 0,5бит 21 = 0,25бит 20 = 0,125бит 19 = 0,0625бит 18 = 0,03125бит 17 = 0,015625..бит 6 = 0,00000762939453125бит 5 = 0,000003814697265625бит 4 = 0,0000019073486328125бит 3 = 0,00000095367431640625бит 2 = 0,000000476837158203125бит 1 = 0,0000002384185791015625бит 0 = 0,00000011920928955078125

Мантисса в этом примере имеет три установленных бита: бит 23, бит 22 и бит 19. Теперь мы можем декодировать мантису, сложив значения, представленные этими битами.

  • Расшифрованная мантисса: 1 + 0.5 + 0.0625 = 1.5625 = C80000 / 2 23 {\displaystyle 1+0.5+0.0625=1.5625={\text{C80000}}/2^{23}}

Затем нам нужно умножить на основание 2 в степени показателя, чтобы получить окончательный результат:

1.5625 × 2 4 = 25 {\displaystyle 1.5625\times 2^{4}=25}

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

41C8 0000 = 25 {\displaystyle {\text{41C8 0000}}=25}

Это эквивалентно:

n = ( 1 ) s × ( 1 + m 2 23 ) × 2 x 127 {\displaystyle n=(-1)^{s}\times (1+m*2^{-23})\times 2^{x-127}}

где s — знаковый бит, x — показатель степени, а m — мантисса.

Ограничения точности десятичных значений (от 1 до 16777216)

  • Десятичные числа от 1 до 2: фиксированный интервал 2 −23 (1+2 −23 — следующее по величине число с плавающей точкой после 1)
  • Десятичные дроби от 2 до 4: фиксированный интервал 2 −22
  • Десятичные дроби от 4 до 8: фиксированный интервал 2 −21
  • ...
  • Десятичные дроби от 2 n до 2 n+1 : фиксированный интервал 2 n-23
  • ...
  • Десятичные дроби между 2 22 =4194304 и 2 23 =8388608: фиксированный интервал 2 −1 =0,5
  • Десятичные дроби между 2 23 =8388608 и 2 24 =16777216: фиксированный интервал 2 0 =1

Ограничения точности целочисленных значений

  • Целые числа от 0 до 16777216 могут быть представлены точно (также применимо к отрицательным целым числам от −16777216 до 0)
  • Целые числа от 2 24 =16777216 до 2 25 =33554432 округляются до кратного 2 (четного числа)
  • Целые числа от 2 25 до 2 26 округляются до кратного 4.
  • ...
  • Целые числа от 2 n до 2 n+1 округляются до кратного 2 n-23
  • ...
  • Целые числа от 2 127 до 2 128 округляются до кратного 2 104.
  • Целые числа, большие или равные 2 128, округляются до «бесконечности».

Известные случаи одинарной точности

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

0 00000000 00000000000000000000001 2 = 0000 0001 16 = 2 −126 × 2 −23 = 2 −149 ≈ 1,4012984643 × 10 −45 (наименьшее положительное субнормальное число)
0 00000000 11111111111111111111111111 2 = 007f ffff 16 = 2 −126 × (1 − 2 −23 ) ≈ 1,1754942107 ×10 −38 (наибольшее субнормальное число)
0 00000001 00000000000000000000000 2 = 0080 0000 16 = 2 −126 ≈ 1,1754943508 × 10 −38 (наименьшее положительное нормальное число)
0 11111110 1111111111111111111111111 2 = 7f7f ffff 16 = 2 127 × (2 − 2 −23 ) ≈ 3,4028234664 × 10 38 (наибольшее нормальное число)
0 01111110 1111111111111111111111111 2 = 3f7f ffff 16 = 1 − 2 −24 ≈ 0,999999940395355225 (наибольшее число меньше единицы)
0 01111111 0000000000000000000000000 2 = 3f80 0000 16 = 1 (один)
0 01111111 00000000000000000000001 2 = 3f80 0001 16 = 1 + 2 −23 ≈ 1,00000011920928955 (наименьшее число больше единицы)
1 10000000 00000000000000000000000 2 = с000 0000 16 = −20 00000000 00000000000000000000000 2 = 0000 0000 16 = 01 00000000 00000000000000000000000 2 = 8000 0000 16 = −0 0 11111111 0000000000000000000000000 2 = 7f80 0000 16 = бесконечность1 11111111 0000000000000000000000000 2 = ff80 0000 16 = −бесконечность 0 10000000 10010010000111111011011 2 = 4049 0fdb 16 ≈ 3,14159274101257324 ≈ π (пи)0 0 01111101 01010101010101010101011 2 = 3eaa aaab 16 ≈ 0,333333343267440796 ≈ 1/3 x 11111111 1000000000000000000000001 2 = ffc0 0001 16 = qNaN (на процессорах x86 и ARM)x 11111111 0000000000000000000000001 2 = ff80 0001 16 = sNaN (на процессорах x86 и ARM)

По умолчанию 1/3 округляет вверх, а не вниз, как двойная точность , из-за четного числа бит в значащей части. Биты 1/3 за точкой округления — это 1010...те, которые больше 1/2 единицы в последнем разряде .

Кодировки qNaN и sNaN не определены в IEEE 754 и реализованы по-разному на разных процессорах. Процессоры семейства x86 и ARM используют старший бит поля мантиссы для указания тихого NaN . Процессоры PA-RISC используют бит для указания сигнального NaN .

Оптимизации

Формат с плавающей точкой допускает различные оптимизации, возникающие из-за простого создания аппроксимации логарифма по основанию 2 из целочисленного представления необработанного битового шаблона. Целочисленная арифметика и сдвиг битов могут дать аппроксимацию обратного квадратного корня ( быстрый обратный квадратный корень ), обычно требуемую в компьютерной графике .

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

Ссылки

  1. ^ "REAL Statement". scc.ustc.edu.cn . Архивировано из оригинала 2021-02-24 . Получено 2013-02-28 .
  2. ^ "CLHS: Тип SHORT-FLOAT, SINGLE-FLOAT, DOUBLE-FLOAT..." www.lispworks.com .
  3. ^ "Примитивные типы данных". Документация Java .
  4. ^ "6 предопределенных типов и классов". haskell.org . 20 июля 2010 г.
  5. ^ "Float". Документация разработчика Apple .
  6. Уильям Кахан (1 октября 1997 г.). «Конспект лекций о состоянии стандарта IEEE 754 для двоичной арифметики с плавающей точкой» (PDF) . стр. 4. Архивировано из оригинала (PDF) 8 февраля 2012 г.
  • Редактор битовых шаблонов с плавающей точкой в ​​реальном времени
  • Онлайн калькулятор
  • Онлайн-конвертер чисел IEEE 754 с одинарной точностью
  • Исходный код C для преобразования между двойной, одинарной и половинной точностью IEEE
Retrieved from "https://en.wikipedia.org/w/index.php?title=Single-precision_floating-point_format&oldid=1252652208"