Системы счисления

From AsIsWiki
(Difference between revisions)
Jump to: navigation, search
 
Line 63: Line 63:
 
Название "шестнадцатеричный" произошло от числа 16. Цифры 0 ... 9 одинаковы и для шестнадцатеричной, и для десятичной систем счисления. Шестнадцатеричные цифры от A до F соответствуют десятичным числам от 10 до 15. Соответствие между десятичными числами (Decimal) и шестнадцатеричными (Hexadecimal) можно представить в виде таблицы:
 
Название "шестнадцатеричный" произошло от числа 16. Цифры 0 ... 9 одинаковы и для шестнадцатеричной, и для десятичной систем счисления. Шестнадцатеричные цифры от A до F соответствуют десятичным числам от 10 до 15. Соответствие между десятичными числами (Decimal) и шестнадцатеричными (Hexadecimal) можно представить в виде таблицы:
  
{| class="wikitable" width=100 style="float:right; text-align:center;"
+
{| class="wikitable" width=100 style="float:right; text-align:center; margin-left:7px;"
 
!dec||hex
 
!dec||hex
 
|-
 
|-
Line 122: Line 122:
 
|height="50"|3||складываем полученные числа||160 + 7 = 167
 
|height="50"|3||складываем полученные числа||160 + 7 = 167
 
|}
 
|}
 
<br><br><br><br><br><br><br><br><br><br>
 
  
 
Шестнадцатеричное число A7h соответствует десятичному числу 167.<br>
 
Шестнадцатеричное число A7h соответствует десятичному числу 167.<br>
Line 134: Line 132:
 
</font>
 
</font>
  
<br>
+
 
 
Примеры перевода чисел из одной системы счисления в другую:
 
Примеры перевода чисел из одной системы счисления в другую:
  
<table width=640>
+
<table width=580>
<tr><td>Перевод числа 2E8h в десятичную форму:</td><td>Перевод числа AF1Ch в десятичную форму:</td></tr>
+
<tr><td>Перевод 2E8h в десятичную форму:</td><td>Перевод AF1Ch в десятичную форму:</td></tr>
 
<tr>
 
<tr>
 
<td valign=top>
 
<td valign=top>
Line 159: Line 157:
 
</tr>
 
</tr>
 
<tr><td><br></td><td><br></td></tr>
 
<tr><td><br></td><td><br></td></tr>
<tr><td>Весовые коэффициенты:</td><td>Перевод числа 3B8D2h в десятичную форму:</td></tr>
+
<tr><td>Весовые коэффициенты:</td><td>Перевод 3B8D2h в десятичную форму:</td></tr>
 
<tr><td valign=top>
 
<tr><td valign=top>
 
{| class="wikitable" width=120 style="text-align:center;"
 
{| class="wikitable" width=120 style="text-align:center;"
Line 186: Line 184:
 
</table>
 
</table>
  
<br>
+
 
 
Переведите следующие шестнадцатеричные числа в десятичную форму:
 
Переведите следующие шестнадцатеричные числа в десятичную форму:
 
  A7h      100h      4F8Ch
 
  A7h      100h      4F8Ch
Line 291: Line 289:
 
Старший (пятый) разряд запоминается в специальной ячейке памяти и называется - "ПЕРЕПОЛНЕНИЕ".
 
Старший (пятый) разряд запоминается в специальной ячейке памяти и называется - "ПЕРЕПОЛНЕНИЕ".
  
{| class="wikitable" width=90 style="float:right; text-align:center; font-family: Courier;"
+
{| class="wikitable" width=90 style="float:right; text-align:center; font-family: Courier; margin-left:15px;"
 
|-
 
|-
 
|FFFF||-1
 
|FFFF||-1
Line 451: Line 449:
 
       |<u>      word      </u>|
 
       |<u>      word      </u>|
  
{| class="wikitable" width=150 style="float:right; text-align:center; font-family: Courier;"
+
{| class="wikitable" width=150 style="float:right; text-align:center; font-family: Courier; margin-left:25px;"
 
!bin||hex||dec
 
!bin||hex||dec
 
|-
 
|-
Line 539: Line 537:
 
== Дополнительный код ==
 
== Дополнительный код ==
  
{| class="wikitable" width=259 style="float:right; text-align:center; font-family: Courier;"
+
{| class="wikitable" width=259 style="float:right; text-align:center; font-family: Courier; margin-left:25px;"
 
|-
 
|-
 
|<b>0</b>000 0000 0000 0000||0000h
 
|<b>0</b>000 0000 0000 0000||0000h

Latest revision as of 11:08, 5 April 2015

Форум

Оглавление | Дальше


Contents

[edit] Введение

В повседневной деятельности мы привыкли к счету с применением цифр 1, 2, 3 и т. д. Вследствие технических особенностей, компьютер применяет другой метод счета, в котором используется всего две цифры 0 и 1. Например, до пяти компьютер считает так: 1, 10, 11, 100, 101. Числа 10, 11, 100 ... являются двоичными, они базируются на системе счисления, состоящей из двух цифр. Десятичная система состоит из десяти цифр 0 ... 9.

Одно и тоже число можно записать в разных системах счисления. Например: двоичное число 10 соответствует десятичному 2.

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

Изучение шестнадцатеричной системы счисления мы начнем в специальной программе - DEBUG.EXE, которая входит в состав операционной системы Windows.


[edit] Debug

Название Debug произошло от слова "Bugs" (насекомые) - так программисты именуют ошибки в программе.

Используя Debug можно проверить работу программы в пошаговом режиме. Это позволяет найти и исправить возможные ошибки. Данный процесс называется отладка "debugging", отсюда и произошло название программы.

Термин "debugging" (обезжучивание) имеет глубокие корни - он появился в тот день, когда перестал работать компьютер Гарвардского университета Марк 1. После долгих поисков техники обнаружили небольшую моль, попавшую между контактами реле. Они удалили моль и внесли запись в сменный журнал о процессе под названием "debugging", произведенном над Марком.

Наиболее удобной средой для изучения Debug является файл-менеджер FAR. Для запуска Debug необходимо в командной строке FAR-а набрать команду "debug" и нажать [Enter]:

debug <Enter>
-

Дефис означает, что Debug ждет команды. Чтобы покинуть программу наберите команду "Q" (Quit - выход) и нажмите ввод:

-q <Enter>

Для сложение и вычитание двух шестнадцатеричных чисел используем команду "H" (Hex – шестнадцатеричный), например:

-h 3 2 <Enter>
0005 0001

Debug печатает сумму 3 + 2 = 5 и разность 3 - 2 = 1. С числами от 0 до 9 Debug ведет себя как с десятичными числами. Сходство между шестнадцатеричной и десятичной системами заканчивается при получении результата больше девяти, например 9 + 1:

-h 9 1
000A 0008

A - это шестнадцатеричное число, аналог десятичного числа 10. Выполните вычисления: 9 + 2, 9 + 3, 9 + 4, 9 + 5, 9 + 6. В результате получатся остальные числа: B, C, D, E, F. Такой способ записи чисел является очень компактным и удобным с точки зрения представления информации в компьютере.

Debug работает только с шестнадцатеричными числами. Некоторые операции с такими числами могут давать не совсем обычные результаты. Например, сложите 8 + 8:

-h 8 8
0010 0000

10 - это шестнадцатеричное число, аналог десятичного числа 16. Теперь найдите разность между числами 2 и 3:

-h 2 3
0005 FFFF

Разность чисел FFFF - это шестнадцатеричное число, соответствующее единице со знаком минус "-1". Попробуйте получить -2, -3 и другие отрицательные числа.


[edit] Перевод шестнадцатеричных чисел в десятичную форму

Название "шестнадцатеричный" произошло от числа 16. Цифры 0 ... 9 одинаковы и для шестнадцатеричной, и для десятичной систем счисления. Шестнадцатеричные цифры от A до F соответствуют десятичным числам от 10 до 15. Соответствие между десятичными числами (Decimal) и шестнадцатеричными (Hexadecimal) можно представить в виде таблицы:

dec hex
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 A
11 B
12 C
13 D
14 E
15 F
16 10
17 11
18 12
19 13
20 14

Обычно шестнадцатеричные числа помечают специальным символом "h": 12h, F8h, 10h и др. Это позволяет избегать путаницы между десятичными и шестнадцатеричными числами, не содержащими букв: 12 - десятичное, 12h - шестнадцатеричное.

Для перевода чисел из hex- в dec- форму используется очень простой алгоритм.
Например, переведем A7h в десятичную форму:

1 переводим обе цифры в десятичную форму A => 10
7 => 7
2 умножаем каждое число на коэффициент, соответствующий разряду числа (весовой коэффициент) 10 * 161 = 160
7 * 160 = 7
3 складываем полученные числа 160 + 7 = 167

Шестнадцатеричное число A7h соответствует десятичному числу 167.
Данный пример можно записать более компактно:

A => 10 * 161 = 160
7 =>  7 * 160 =   7   перевод числа A7h в десятичную форму
A7h = 160 + 7 = 167


Примеры перевода чисел из одной системы счисления в другую:

Перевод 2E8h в десятичную форму:Перевод AF1Ch в десятичную форму:

   2 =>  2 * 162 = 512
   E => 14 * 161 = 224
   8 =>  8 * 160 =   8    
2E8h = 512 + 224 + 8 = 744

        A => 10 * 163 = 40960
        F => 15 * 162 =  3840
        1 =>  1 * 161 =    16
        C => 12 * 160 =    12         
AF1Ch = 40960 + 3840 + 16 + 12 = 44828



Весовые коэффициенты:Перевод 3B8D2h в десятичную форму:
164 65535
163 4096
162 256
161 16
160 1

      3 =>  3 * 164 = 196608
      B => 11 * 163 =  45056
      8 =>  8 * 162 =   2048
      D => 13 * 161 =    208
      2 =>  2 * 160 =      2      
3B8D2h = 196608 + ... + 2 = 243922


Переведите следующие шестнадцатеричные числа в десятичную форму:

A7h       100h       4F8Ch
45h       5E9h       1000h
FFh       FFFh       FFFFh


[edit] Сложение и вычитание шестнадцатеричных чисел

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

A + 1 = B       B - A = 1       F + 1 = 10       A + C = 16
B - 2 = 9       7 + 7 = E       F + F = 1E       10 - 8 = 8

Рассмотрим, как получается 1Eh в результате сложения F + F. Запишем результат операции в десятичном виде: F + F = 15 + 15 = 30.

Проверим, сколько шестнадцатеричных десятков содержится в числе 30: 30 / 16 = 1 (один десяток). Шестнадцатеричный десяток 10h соответствует десятичному числу 16. Проводим вычитание 30 - 16 и получаем остаток 14, откуда: 14 + 16 = Eh + 10h = 1Eh.

Числа с большим числом разрядов можно складывать "столбиком":

1          1        1           1111         1 1
 C        2A7        F451        BCD8        BCD8
+D       +92A       +CB03       +FAE9       +0509
19        BD1       1BF54       1B7C1        C1E1

Вычислите "столбиком" следующие примеры, а результаты проверьте в Debug:

3F8h + AB9h       4E5h + 4F3h       DF8h - AB9h
FF7h + 8BFh       FFFh + FFFh       FF7h - 8BFh
CD0h + A82h       FFFh + 001h       CD2h - A82h


[edit] Пятизначные шестнадцатеричные числа

Что произойдет, если в сложении использовать пятизначное шестнадцатеричное число? Вычислим сумму следующих чисел:

-h 5C3F0 4BC6
       ^Error

Debug сообщил об ошибке. Команда "h" не может обрабатывать числа, длина которых больше четырех разрядов. Шестнадцатеричное число, состоящее из четырех разрядов называют так: "СЛОВО" или "WORD".

Если сложить два "слова", например C000h и D000h, то вместо действительного результата 19000h получится "урезанный" до четырех разрядов результат 9000h:

-h C000 D000
9000 F000

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

Подумайте, какое значение имеет старший (пятый) разряд при сложении четырехразрядных шестнадцатеричных чисел?


[edit] Перевод десятичных чисел в шестнадцатеричную форму

Перевод десятичного числа в шестнадцатеричную форму выполняется делением исходного числа на 16. Например, переведем 300 в шестнадцатеричную форму:

_300 |16                        То же самое можно записать иначе:
 16  _18 |16                    300 / 16 = 18 остаток 12 => C
_140  16  1 -> 1                 18 / 16 = 1  остаток  2 => 2
 128   2 ----> 2  => 12Ch         1 / 16 = 0  остаток  1 => 1
  12 --------> C                         300 = 12Ch

Примеры перевода чисел 1000 и 60000 в шестнадцатеричную форму:

60000/16 = 3750 остаток  0 => 0       1000/16 = 62 остаток  8 => 8
 3750/16 =  234 остаток  6 => 6         62/16 =  3 остаток 14 => E
  234/16 =   14 остаток 10 => A          3/16 =  0 остаток  3 => 3
   14/16 =    0 остаток 14 => E               1000 = 3E8h
         60000 = EA60h

Переведите следующие числа в шестнадцатеричную форму:

945, 138, 1100, 885, 230, 256, 1024

Шестнадцатеричный результат переведите обратно в десятичную форму - это позволит проверить корректность ваших действий.


[edit] Отрицательные числа

Ранее было отмечено, что FFFFh фактически равно -1. Однако если перевести число FFFFh в десятичную форму, то получится 65535. Почему так происходит? Действительно ли FFFFh ведет себя как отрицательное число?

Пусть так, тогда если сложить FFFFh и 5, то должно получиться 4:

-h 5 FFFF
0004 0006

Похоже, Debug действительно обращается с FFFFh, как с -1. Рассмотрим механизм сложения чисел 5 и FFFFh, при суммировании "столбиком":

1111
 0005
+FFFF
10004   5 + (-1) = 4

Если игнорировать единицу в старшем разряде, то получается правильный ответ 5 + (-1) = 4. Debug сохраняет четыре младшие цифры результата. Старший (пятый) разряд запоминается в специальной ячейке памяти и называется - "ПЕРЕПОЛНЕНИЕ".

FFFF -1
FFFE -2
FFFD -3
FFFC -4
FFFB -5
FFFA -6
FFF9 -7
FFF8 -8
FFF7 -9
FFF6 -A
FFF5 -B
FFF4 -C
FFF3 -D
FFF2 -E
FFF1 -F
FFF0 -10


Сложение чисел, больших чем 8000h дает переполнение. Такие числа ведут себя аналогично отрицательным числам:

1111                       1111
 0008                       FFF0
+FFFA                      +8FFF
10002   8 + (-6) = 2       18FEF   -10h + (-7001h) = -7011h

В последнем примере установлено соответствие чисел 8FEFh и -7011h. Как проверить справедливость этого утверждения? Ранее отмечалось, что FFFFh это (-1), значит FFFEh это (-2) и т.д. В приведенной таблице представлен ряд отрицательных чисел. Если ряд продолжить, то при достижении числа 8FEFh мы увидим его отрицательный эквивалент: -7011h

Любой язык программирования позволяет оперировать двумя типами чисел: знаковыми и беззнаковыми. Представление числа зависит от конкретной ситуации. Например: FFFAh можно рассматривать как число без знака, и как отрицательное число -6. Если в программе нужны отрицательные числа, то диапазон 0 ... FFFFh делится на две части:

   0h ... 7FFFh - положительные числа
8000h ... FFFFh - отрицательные числа

Отрицательный аналог числа 8FEFh называется его дополнительным кодом, и выражается числом -7011h. Рассмотрим алгоритм нахождения дополнительного кода:

  1. Инвертировать исходное число, т.е. заменить все цифры числа на противоположные:
    F => 0, E => 1, D => 2, C => 3, B => 4 и т.д. После инверсии 8FEFh выглядит так: 7010h
  2. К инверсному числу добавить единицу: 7010h + 1 = 7011h - получилось искомое число.

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

0 ... FFFFh или 0 ... 65535

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

-8000h ... 7FFFh или -32768 ... 32767

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

Вычислите дополнительный код следующих чисел:

FF00h, AD3Fh, 9000h, EDF4h, B348h


[edit] Двоичная система счисления

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

0 вольт соответствует цифре "0"
1 вольт соответствует цифре "1"
...
9 вольт соответствует цифре "9"

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

0 ... 0,5 вольт соответствует цифре "0"
2,5 ... 5 вольт соответствует цифре "1"

Такая разница между уровнями сигналов (соответствующих "0" и "1") практически исключает ошибки связанные с колебаниями напряжения и другими искажениями сигнала. Кроме того, значительно упрощается компонентная база компьютера.

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

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

Для вывода на экран чисел в шестнадцатеричном формате, Debug использует небольшую подпрограмму, которая переводит двоичные числа (обрабатываемые микропроцессором), в шестнадцатеричную форму.

Двоичные числа мы будем помечать индексом "b" (binary - двоичный), например: 10010111b

Рассмотрим число 1101b. Все разряды числа характеризуются весовыми коэффициентами, которые получаются возведением основания системы счисления (два) в степень, соответствующую номеру разряда. Нумерация разрядов начинается с нуля.

Для перевода числа из двоичной системы в десятичную, необходимо выбрать весовые коэффициенты тех разрядов, где есть единица (в случае числа 1101b, это: 23, 22 и 20). Далее нужно сложить эти числа: 23 + 22 + 20 = 13

Номера разрядов 3 2 1 0
Весовые коэффициенты 23 22 21 20
Число 1 1 0 1

Перевод числа 11010010b в десятичную форму:

27 26 25 24 23 22 21 20
1 1 0 1 0 0 1 0
27 + 26 + 24 + 21 = 210

Переведите следующие двоичные числа в десятичный формат:

0110b       0101b       10111001b       10101101b
1011b       1001b       10011001b       11111111b

По размеру двоичные числа делятся на следующие:

                  1   бит
               1011   полубайт
          1101 0011   байт
1001 0110 0101 1110   слово

Графически это разделение можно показать так:

sign bit  bit      byte 
      |    |    |       |
      1001 0110 1101 0111
      |       word      |
bin hex dec
0000 0 0
0001 1 1
0010 2 2
0011 3 3
0100 4 4
0101 5 5
0110 6 6
0111 7 7
1000 8 8
1001 9 9
1010 A 10
1011 B 11
1100 C 12
1101 D 13
1110 E 14
1111 F 15

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

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

            1111b = Fh      двоичный полубайт
        11111111b = FFh     двоичный байт
1111111111111111b = FFFFh   двоичное слово

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

1001001001011011b => 1001.0010.0101.1011b

Каждая декада переводится в шестнадцатеричный формат, аналогично преобразованию чисел из двоичной системы счисления в десятичную:

1001b = 23 + 20      =  9 => 9
0010b = 21           =  2 => 2
0101b = 22 + 20      =  5 => 5
1011b = 23 + 21 + 20 = 11 => B
1001.0010.0101.1011b = 925Bh

Переведите следующие числа в шестнадцатеричную форму:

1111b       1110b       10101001b
1010b       1001b       10001001b
1011b       1101b       11111111b

Арифметические действия с двоичными числами выполняются аналогично действиям с десятичными числами. Например, сложение одноразрядных двоичных чисел выглядит так:

                  1
 1        0        1
+0       +1       +1
 1        1       10

Сложение четырехразрядных и восьмиразрядных двоичных чисел:

1111                       111111
 1101                      01101110
+0011                     +01011010
10000   13 + 3 = 16        11001000   110 + 90 = 200

Выполните следующие действия:

0101 + 1100       10100011 + 00110011
1110 + 0011       10110011 + 01011100

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


[edit] Дополнительный код

0000 0000 0000 0000 0000h
... ...
0111 1111 1111 1111 7FFFh
1000 0000 0000 0000 8000h
... ...
1111 1111 1111 1111 FFFFh

Раннее отмечалось, что в некоторых случаях числа 8000h ... FFFFh ведут себя как отрицательные.
Рассмотрим числа 0 ... FFFFh в двоичной системе счисления. Данный ряд делится на две равные части. Cтарший бит, в двоичном представлении чисел, выделен жирным шрифтом. Начиная с числа 8000h, старший бит устанавливается в единицу.

Старший бит является признаком отрицательного числа. По его состоянию микропроцессор определяет знак числа. Но если в программе используются команды для чисел без знака, то микропроцессор игнорирует знаковый бит, и воспринимает диапазон [0 ... FFFFh] как ряд положительных чисел.

Числа, в которых старший бит используется для хранения знака, известны как двоичное дополнение положительных чисел или дополнительный код.

Ранее мы находили дополнительный код шестнадцатеричных чисел (вспомните инверсию шестнадцатеричного числа с добавлением единицы). Дополнительный код двоичного числа определяется аналогично. Например, найдем дополнительный код числа 1101011010001001:

 1101.0110.1000.1001  (D689h)
          ↓                   инвертируем число
 0010.1001.0111.0110
+                  1          добавляем к результату единицу
 0010.1001.0111.0111 (-2977h)

Вычитание двоичных чисел, например A - B, сводится к их сложению A + (-B). При этом: A не меняется, B преобразуется в дополнительный код. Далее числа складываются. Например, надо произвести вычитание 1101b - 1010b:

1. Преобразуем 1010 в дополнительный код:

1010 => 0101 => 0101 + 1 => 0110

2. Выполняем сложение:

11
 1101     1101 + (-1010) => 0011 или 13 + (-10) => 3
+0110
10011     (единица в старшем разряде игнорируется)

Выполните следующие действия:

1110 - 0011       11110000 - 00110111
1001 - 0110       01110110 - 00111001



Форум

Оглавление | Дальше

Personal tools
Namespaces

Variants
Actions
Navigation
Tools