Кодировка чисел в памяти ЭВМ

Целые числа

К настоящему моменту почти любая ЭВМ использует память, подразделяющуюся на байты — восьмёрки бит. Каждый бит может принимать одно из двух значений (будем их обозначать 0 и 1). Соответственно, каждый байт может принимать одно из двухсот пятидесяти шести значений. Для записи этих значений обычно используют пары шестнадцатиричных цифр: 00, 01, 02, … ff.

Соответственно, для записи целых чисел в память ЭВМ обычно используют 256-ричную систему счисления. При этом различают несколько форматов записи. У каждого формата есть:

  • порядок цифр (байт): Little Endian (от младших цифр к старшим) и Big Endian (от старших цифр к младшим)
  • количество байт: обычно 1, 2, 4, 8 или 16
  • диапазон: «без знака» (от \(0\) до \(N-1\)) или «со знаком» (от \(-N/2\) до \(N/2 - 1\)), где \(N\) — общее количество комбинаций используемых байт

При этом для записи чисел диапазона «без знака» используется обычная 256-ричная система счисления, а числа диапазона «со знаком» записываются так же, как их остатки по модулю \(N\) в формате «без знака».

Например, в 2-байтовом LE-формате без знака число \(1234\) имеет вид d2 04.

А в 1-байтовом формате со знаком число \((-123)\) записывается так же, как и \(256-123=133\) без знака: 85.

Числа с плавающей точкой

Для записи рациональных чисел обычно используется формат с плавающей точкой. Устроен он так: все биты кода (который обычно имеет ширину 16 бит, 32 бита или же 64 бита) делятся на три части:

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

Для стандартных форматов используются следующие размеры экспонент:

  • 16 бит («половинная» точность) — 5-битная экспонента
  • 32 бита («одинарная» точность) — 8-битная экспонента
  • 64 бита («двойная» точность) — 11-битная экспонента

Знак задаёт луч, на котором находится число. Знак 0 — неотрицательные числа, знак 1 — неположительные.

Луч (будем все его точки обозначать расстоянием до нуля) разбивается на отрезки:

  • нулевой — от \(0\) до \(2^{-N}\) для некоторого \(N\)
  • первый — от \(2^{-N}\) до \(2^{-N+1}\)
  • каждый следующий получается из предыдущего умножением на два

При этом отрезок от \(1\) до \(2\) имеет номер вида \(01\ldots1\) (здесь 4, 7 или 10 единиц).

Экспонента (кроме экспоненты \(1\ldots 1\), которая зарезервирована) — (записанный двоично) номер такого отрезка. Числа с нулевой экспонентой называются денормализованными.

Далее каждый отрезок разбивается на одинаковые части (количеством, равным количеству всевозможных значений мантиссы). Мантисса — порядковый номер левого деления такой части.

Итого, если знак равен \(s\), экспонента равна \(e\) и отлична от крайних значений, мантисса равна \(m\), ширина экспоненты равна \(E\) бит, а ширина мантиссы равна \(M\), то эти данные кодируют число

\[ (-1)^s \cdot 2^{1 + e - 2^{E-1}} \cdot (1 + m\cdot 2^{-M}) \]

В конце концов биты разбиваются на байты и записываются в LE- или BE-порядке.

Пример

Чтобы закодировать число \((-23.75\) в LE-формат половинной точности, проведём следующие действия.

Знак равен 1 (т.к. число отрицательное).

Подберём экспоненту:

  • 01111 соответствует отрезку от 1 до 2
  • 10000 соответствует отрезку от 2 до 4
  • 10001 соответствует отрезку от 4 до 8
  • 10010 соответствует отрезку от 8 до 16
  • 10011 соответствует отрезку от 16 до 32

Последний отрезок нам и нужен.

Теперь будем определять мантиссу:

  • мантиссы с началом 0 кодируют числа отрезка от 16 до 24
  • мантиссы с началом 01 кодируют числа отрезка от 20 до 24
  • мантиссы с началом 011 кодируют числа отрезка от 22 до 24
  • мантиссы с началом 0111 кодируют числа отрезка от 23 до 24
  • мантиссы с началом 01111 кодируют числа отрезка от 23.5 до 24
  • мантиссы с началом 011111 кодируют числа отрезка от 23.75 до 24

Нам как раз нужно начальное число последнего отрезка. Поэтому наша мантисса имеет вид 0111110000.

Итого биты нашего числа: 1 10011 0111110000. Их 256-ричная запись: cd f0.

Осталось записать эти два байта в формате LE: f0 cd.