Способы кодирования двоичным кодом целые числа

Содержание
  1. Представление числовых данных в памяти ЭВМ
  2. Кодирование символов
  3. Двоично-десятичное кодирование
  4. Представление целых чисел в дополнительном коде
  5. Кодирование вещественных чисел
  6. Представление целых чисел: прямой код, код со сдвигом, дополнительный код
  7. Содержание
  8. Прямой код [ править ]
  9. Достоинства представления чисел с помощью прямого кода [ править ]
  10. Недостатки представления чисел с помощью прямого кода [ править ]
  11. Код со сдвигом [ править ]
  12. Достоинства представления чисел с помощью кода со сдвигом [ править ]
  13. Недостатки представления чисел с помощью кода со сдвигом [ править ]
  14. Дополнительный код (дополнение до единицы) [ править ]
  15. Достоинства представления чисел с помощью кода с дополнением до единицы [ править ]
  16. Недостатки представления чисел с помощью кода с дополнением до единицы [ править ]
  17. Дополнительный код (дополнение до двух) [ править ]
  18. Длинная арифметика для чисел, представленных с помощью кода с дополнением до двух [ править ]
  19. Достоинства представления чисел с помощью кода с дополнением до двух [ править ]
  20. Недостатки представления чисел с помощью кода с дополнением до двух [ править ]

Представление числовых данных в памяти ЭВМ

Для представления информации в памяти ЭВМ (как числовой, так и не числовой) используется двоичный способ кодирования.

Элементарная ячейка памяти ЭВМ имеет длину 8 бит (байт). Каждый байт имеет свой номер (его называют адресом ). Наибольшую последовательность бит, которую ЭВМ может обрабатывать как единое целое, называют машинным словом . Длина машинного слова зависит от разрядности процессора и может быть равной 16, 32, 64 битам и т.д.

Кодирование символов

Для кодирования символов достаточно одного байта. При этом можно представить 256 символов (с десятичными кодами от 0 до 255). Набор символов персональных ЭВМ, совместимых с IBM PC, чаще всего является расширением кода ASCII (American Standard Code for Information Interchange — стандартный американский код для обмена информацией). В настоящее время используются и двухбайтовые предсталения символов.

Двоично-десятичное кодирование

В некоторых случаях при представлении чисел в памяти ЭВМ используется смешанная двоично-десятичная «система счисления», где для хранения каждого десятичного знака нужен полубайт (4 бита) и десятичные цифры от 0 до 9 представляются соответствующими двоичными числами от 0000 до 1001. Например, упакованный десятичный формат, предназначенный для хранения целых чисел с 18-ю значащими цифрами и занимающий в памяти 10 байт (старший из которых знаковый), использует именно этот вариант.

Представление целых чисел в дополнительном коде

Другой способ представления целых чисел — дополнительный код . Диапазон значений величин зависит от количества бит памяти, отведенных для их хранения. Например, величины типа Integer (все названия типов данных здесь и ниже представлены в том виде, в каком они приняты в языке программирования Turbo Pascal. В других языках такие типы данных тоже есть, но могут иметь другие названия) лежат в диапазоне от -32768 (-2 15 ) до 32767 (2 15 — 1) и для их хранения отводится 2 байта (16 бит); типа LongInt — в диапазоне от -2 31 до 2 31 — 1 и размещаются в 4 байтах (32 бита); типа Word — в диапазоне от 0 до 65535 (2 16 — 1) (используется 2 байта) и т.д.

Как видно из примеров, данные могут быть интерпретированы как числа со знаком , так и без знака . В случае представления величины со знаком самый левый (старший) разряд указывает на положительное число, если содержит нуль, и на отрицательное, если — единицу.

Вообще, разряды нумеруются справа налево, начиная с 0. Ниже показана нумерация бит в двухбайтовом машинном слове.

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

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

Например, если число 37 (10) = 100101 (2) объявлено величиной типа Integer ( шестнадцатибитовое со знаком ), то его прямым кодом будет 0000000000100101, а если величиной типа LongInt ( тридцатидвухбитовое со знаком ), то его прямой код будет 00000000000000000000000000100101. Для более компактной записи чаще используют шестнадцатеричное представление кода. Полученные коды можно переписать соответственно как 0025 (16) и 00000025 (16) .

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

  1. записать прямой код модуля числа;
  2. инвертировать его (заменить единицы нулями, нули — единицами);
  3. прибавить к инверсному коду единицу.

Например, запишем дополнительный код числа -37, интерпретируя его как величину типа LongInt (тридцатидвухбитовое со знаком):

  1. прямой код числа 37 есть 00000000000000000000000000100101;
  2. инверсный код 11111111111111111111111111011010;
  3. дополнительный код 11111111111111111111111111011011 или FFFFFFDB(16).

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

  1. вычесть из кода числа 1;
  2. инвертировать код;
  3. перевести в десятичную систему счисления. Полученное число записать со знаком минус.

Примеры. Запишем числа, соответствующие дополнительным кодам:

  1. 0000000000010111. Поскольку в старшем разряде записан нуль, то результат будет положительным. Это код числа 23.
  2. 1111111111000000. Здесь записан код отрицательного числа. Исполняем алгоритм: 1) 1111111111000000(2) — 1(2) = 1111111110111111(2); 2) 0000000001000000; 3) 1000000(2) = 64(10).
    Ответ: -64.

Кодирование вещественных чисел

Несколько иной способ применяется для представления в памяти персонального компьютера действительных чисел. Рассмотрим представление величин с плавающей точкой.

Любое действительное число можно записать в стандартном виде M × 10 p , где 1 £ M p — целое. Например, 120100000 = 1,201 × 10 8 . Поскольку каждая позиция десятичного числа отличается от соседней на степень числа 10, умножение на 10 эквивалентно сдвигу десятичной запятой на одну позицию вправо. Аналогично деление на 10 сдвигает десятичную запятую на позицию влево. Поэтому приведенный выше пример можно продолжить: 120100000 = 1,201 × 10 8 = 0,1201 × 10 9 = 12,01 × 10 7 . Десятичная запятая «плавает» в числе и больше не помечает абсолютное место между целой и дробной частями.

В приведенной выше записи M называют мантиссой числа, а p — его порядком. Для того чтобы сохранить максимальную точность, вычислительные машины почти всегда хранят мантиссу в нормализованном виде, что означает, что мантисса в данном случае есть число, лежащее между 1(10) и 2(10) (1 £ M

Тип Диапазон Мантисса Байты
Real 2,9×10 -39 ..1,7×10 38 11-12 6
Single 1,5×10 -45 ..3,4×10 38 7-8 4
Double 5,0×10 -324 ..1,7×10 308 15-16 8
Extended 3,4×10 -4932 ..1,1×10 4932 19-20 10

Покажем преобразование действительного числа для представления его в памяти ЭВМ на примере величины типа Double.

Как видно из таблицы, величина это типа занимает в памяти 8 байт. На рисунке ниже показано, как здесь представлены поля мантиссы и порядка (нумерация битов осуществляется справа налево):

S Смещенный порядок Мантисса
63 62..52 51..0

Можно заметить, что старший бит, отведенный под мантиссу, имеет номер 51, т.е. мантисса занимает младшие 52 бита. Черта указывает здесь на положение двоичной запятой. Перед запятой должен стоять бит целой части мантиссы, но поскольку она всегда равна 1, здесь данный бит не требуется и соответствующий разряд отсутствует в памяти (но он подразумевается). Значение порядка хранится здесь не как целое число, представленное в дополнительном коде. Для упрощения вычислений и сравнения действительных чисел значение порядка в ЭВМ хранится в виде смещенного числа, т.е. к настоящему значению порядка перед записью его в память прибавляется смещение. Смещение выбирается так, чтобы минимальному значению порядка соответствовал нуль. Например, для типа Double порядок занимает 11 бит и имеет диапазон от 2 -1023 до 2 1023 , поэтому смещение равно 1023(10) = 1111111111(2). Наконец, бит с номером 63 указывает на знак числа.

Таким образом, из вышесказанного вытекает следующий алгоритм для получения представления действительного числа в памяти ЭВМ:

  1. перевести модуль данного числа в двоичную систему счисления;
  2. нормализовать двоичное число, т.е. записать в виде M × 2 p , где M — мантисса (ее целая часть равна 1(2)) и p — порядок, записанный в десятичной системе счисления;
  3. прибавить к порядку смещение и перевести смещенный порядок в двоичную систему счисления;
  4. учитывая знак заданного числа (0 — положительное; 1 — отрицательное), выписать его представление в памяти ЭВМ.

Пример. Запишем код числа -312,3125.

  1. Двоичная запись модуля этого числа имеет вид 100111000,0101.
  2. Имеем 100111000,0101 = 1,001110000101 × 2 8 .
  3. Получаем смещенный порядок 8 + 1023 = 1031. Далее имеем 1031(10) = 10000000111(2).
  4. Окончательно
    1 10000000111 0011100001010000000000000000000000000000000000000000
    63 62..52 51..0

Очевидно, что более компактно полученный код стоит записать следующим образом: C073850000000000(16).

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

Источник

Представление целых чисел: прямой код, код со сдвигом, дополнительный код

Выбор способа хранения целых чисел в памяти компьютера — не такая тривиальная задача, как могло бы показаться на первый взгляд. Желательно, чтобы этот способ:

  • не требовал усложнения архитектуры процессора для выполнения арифметических операций с отрицательными числами,
  • не усложнял арифметические действия,
  • хранил бы одинаковое количество положительных и отрицательных чисел.

Рассмотрим разные методы представления.

Содержание

Прямой код [ править ]

При записи числа в прямом коде (англ. Signed magnitude representation) старший разряд является знаковым разрядом. Если его значение равно нулю, то представлено положительное число или положительный ноль, если единице, то представлено отрицательное число или отрицательный ноль. В остальных разрядах (которые называются цифровыми) записывается двоичное представление модуля числа. Например, число [math] -5 [/math] в восьмибитном типе данных, использующем прямой код, будет выглядеть так: [math] 10000101 [/math] .

Таким способом в [math] n [/math] -битовом типе данных можно представить диапазон чисел [math] [-2^ + 1; 2^ — 1] [/math] .

Достоинства представления чисел с помощью прямого кода [ править ]

  1. Получить прямой код числа достаточно просто.
  2. Из-за того, что [math]0[/math] обозначает [math]+[/math] , коды положительных чисел относительно беззнакового кодирования остаются неизменными.
  3. Количество положительных чисел равно количеству отрицательных.

Недостатки представления чисел с помощью прямого кода [ править ]

  1. Выполнение арифметических операций с отрицательными числами требует усложнения архитектуры центрального процессора (например, для вычитания невозможно использовать сумматор, необходима отдельная схема для этого).
  2. Существуют два нуля: [math] -0 [/math] [math](100 \ldots 000) [/math] и [math] +0 [/math] [math] (000 \ldots 000) [/math] , из-за чего усложняется арифметическое сравнение.

Из-за весьма существенных недостатков прямой код используется очень редко.

Код со сдвигом [ править ]

При использовании кода со сдвигом (англ. Offset binary) целочисленный отрезок от нуля до [math] 2^n [/math] ( [math] n [/math] — количество бит) сдвигается влево на [math] 2^ [/math] , а затем получившиеся на этом отрезке числа последовательно кодируются в порядке возрастания кодами от [math] 000 \dots 0 [/math] до [math] 111 \dots 1 [/math] . Например, число [math] -5 [/math] в восьмибитном типе данных, использующем код со сдвигом, превратится в [math] -5 + 128 = 123 [/math] , то есть будет выглядеть так: [math] 01111011 [/math] .

По сути, при таком кодировании:

  • к кодируемому числу прибавляют [math] 2^ [/math] ;
  • переводят получившееся число в двоичную систему исчисления.

Можно получить диапазон значений [math] [-2^; 2^ — 1][/math] .

Достоинства представления чисел с помощью кода со сдвигом [ править ]

  1. Не требуется усложнение архитектуры процессора.
  2. Нет проблемы двух нулей.

Недостатки представления чисел с помощью кода со сдвигом [ править ]

  1. При арифметических операциях нужно учитывать смещение, то есть проделывать на одно действие больше (например, после «обычного» сложения двух чисел у результата будет двойное смещение, одно из которых необходимо вычесть).
  2. Ряд положительных и отрицательных чисел несимметричен.

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

Дополнительный код (дополнение до единицы) [ править ]

В качестве альтернативы представления целых чисел может использоваться код с дополнением до единицы (англ. Ones’ complement).

Алгоритм получения кода числа:

  • если число положительное, то в старший разряд (который является знаковым) записывается ноль, а далее записывается само число;
  • если число отрицательное, то код получается инвертированием представления модуля числа (получается обратный код);
  • если число является нулем, то его можно представить двумя способами: [math] +0 [/math] [math](000 \ldots 000) [/math] или [math] -0 [/math] [math] (111 \ldots 111) [/math] .

Пример: переведём число [math] -13 [/math] в двоичный восьмибитный код. Прямой код модуля [math] -13 [/math] : [math] 00001101 [/math] , инвертируем и получаем [math] 11110010 [/math] . Для получения из дополнительного кода самого числа достаточно инвертировать все разряды кода.

Таким способом можно получить диапазон значений [math] [-2^+1; 2^ — 1] [/math] .

Достоинства представления чисел с помощью кода с дополнением до единицы [ править ]

  1. Простое получение кода отрицательных чисел.
  2. Из-за того, что [math]0[/math] обозначает [math]+[/math] , коды положительных чисел относительно беззнакового кодирования остаются неизменными.
  3. Количество положительных чисел равно количеству отрицательных.

Недостатки представления чисел с помощью кода с дополнением до единицы [ править ]

  1. Выполнение арифметических операций с отрицательными числами требует усложнения архитектуры центрального процессора.
  2. Существуют два нуля: [math] +0 [/math] и [math] -0 [/math] .

Дополнительный код (дополнение до двух) [ править ]

Чаще всего для представления отрицательных чисел используется код с дополнением до двух (англ. Two’s complement).

Алгоритм получения дополнительного кода числа:

  • если число неотрицательное, то в старший разряд записывается ноль, далее записывается само число;
  • если число отрицательное, то все биты модуля числа инвертируются, то есть все единицы меняются на нули, а нули — на единицы, к инвертированному числу прибавляется единица, далее к результату дописывается знаковый разряд, равный единице.

В качестве примера переведём число [math] -5 [/math] в дополнительный восьмибитный код. Прямой код модуля [math] -5 [/math] : [math] 0000101 [/math] , обратный — [math] 1111010 [/math] , прибавляем [math] 1 [/math] , получаем [math] 1111011 [/math] , приписываем [math] 1 [/math] в качестве знакового разряда, в результате получаем [math] 11111011 [/math] .

Также дополнительный код отрицательного числа [math] A [/math] , хранящегося в [math] n [/math] битах, равен [math] 2^n — |A| [/math] . По сути, дополнительный код представляет собой дополнение [math] |A| [/math] до [math] 0 [/math] : так как в [math] n [/math] -разрядной арифметике [math] 2^ = 0 [/math] (двоичная запись этого числа состоит из единицы и [math] n [/math] нулей, а в [math] n [/math] -разрядную ячейку помещаются только [math] n [/math] младших разрядов, то есть [math] n [/math] нулей), то верно равенство [math] 2^n — |A| + |A| = 0 [/math] .

Для получения из дополнительного кода самого числа нужно инвертировать все разряды кода и прибавить к нему единицу. Можно проверить правильность, сложив дополнительный код с самим числом: результат должен быть равен [math] 2^n [/math] . Переведём [math] 11111011 [/math] обратно. Инвертируем — [math] 00000100 [/math] , прибавляем [math] 1 [/math] , получаем [math] 00000101 [/math] — модуль исходного числа [math] -5 [/math] . Проверим: [math] 11111011 + 00000101 = 100000000 [/math] .

Можно получить диапазон значений [math] [-2^; 2^ — 1] [/math] .

Длинная арифметика для чисел, представленных с помощью кода с дополнением до двух [ править ]

Дополнительный код также удобно использовать для вычислений в длинной арифметике, особенно для операций сложения и вычитания. Это операции удобно выполнять с числами одинаковой длины, поэтому в старшие разряды меньшего числа нужно поместить нули (если число положительно) или единицы (если число отрицательно). Тогда числа будут выглядеть следующим образом: в старших разрядах бесконечное число нулей (единиц), а в младших разрядах уже встречаются и нули, и единицы, которые кодируют само число, а не знак. Удобство заключается в том, что нам не обязательно проделывать операции сложения с каждой парой бит, если мы знаем, что на этом отрезке в числах стоят либо единицы, либо нули. Таким образом, на этом отрезке в получившемся числе тоже будут либо только единицы, либо только нули. Операцию сложения можно выполнить только один раз для старших битов, таким образом мы узнаем знак получившегося числа. Вычитание тоже выполняется просто: инвертируем число, прибавляем один и получаем это число с минусом, затем просто делаем сложение. Однако умножение с числами, представленными дополнительным кодом, выполнять не всегда оптимально: алгоритм либо слишком медленный (наивный алгоритм работает за [math]O(n^2)[/math] ), либо слишком сложный. Лучше для умножение использовать прямой код (бит под знак). Тогда можно числа перевести в десятичную систему счисления, выполнить быстрое преобразование Фурье за [math]O(n \log n)[/math] , затем перевести их обратно в двоичную. Обычно такой алгоритм работает быстрее, чем выполнение операции напрямую с двоичными числами. Для деления обычно тоже лучше использовать прямой код.

Достоинства представления чисел с помощью кода с дополнением до двух [ править ]

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

Недостатки представления чисел с помощью кода с дополнением до двух [ править ]

  1. Ряд положительных и отрицательных чисел несимметричен, но это не так важно: с помощью дополнительного кода выполнены гораздо более важные вещи, желаемые от способа представления целых чисел.
  2. В отличие от сложения, числа в дополнительном коде нельзя сравнивать как беззнаковые, или вычитать без расширения разрядности.

Несмотря на недостатки, дополнение до двух в современных вычислительных системах используется чаще всего.

Источник

Читайте также:  Способы движения животных проект
Оцените статью
Разные способы