Представление данных — Компьютерные системы, часть 2

Представление данных — Компьютерные системы, часть 2

Оглавление

2. Представление данных

Биты и информация

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

Один провод может находится под высоким напряжением (напряжение присутствует), либо по низким (напряжение отсутствует). Конкретные значения напряжения зависят от конструкции компьютера, важным для нас является факт наличия этой дуальности.

Место, которое может пребывать в двух состояниях мы будем называть битом. Один провод несет в себе один бит. Мы можем объединить несколько битов для преставления более сложных данных. 8 битов называют одним байтов. Например один байт может содержать следующее значение: 10011110. В целом 1 байт может содержать в себе 2^8=256 различных значений. N бит могут содержать 2^N значений. Давайте рассмотрим, какие типы данных мы можем представить, используя биты.

Представление натуральных чисел

Натуральные числа – это все целые числа, начиная от нуля и до бесконечности.  Поскольку у нас всего два типа сигналов, для представления натуральных чисел, нам необходимо использовать двоичную систему счисления. В быту мы чаще пользуемся десятичной системой. Как она работает? Рассмотрим, например число 285. 5 в нем означает количество единиц, 8 – количество десяток, 2 – количество сотен. Как видно, каждая цифра означает количество степеней десяток. 285 = 2*10^2 + 8 * 10^1 + 5 * 10^0. Двоичная система основана на тех же принципах, но каждая цифра в двоичном числе означает количество степеней двоек , а не десяток. Последняя цифра в таком числе будет означать количество единиц (2^0), так которая левее – количество двоек (2^1), так которая еще левее количество четверок (2^2) и т.д.

Например 10011 = 1*2^4 + 0*2^3 + 0 * 2^2 + 1*2^1 + 1*2^0 = 19. Таким образом мы можем использовать двоичную систему счисления и представить любое натуральное число с помощью единиц и нулей. Сложить два двоичных числа можно на основе тех же принципов, на основе каких мы складываем десятичные числа. Например, 10011 + 10110 

 10011
 10110
101000 

1+0=0
1+1=10 – ноль пишем, единицу переносим
0+1+1=10 – ноль пишем, единицу переносим
0+0+1=1
1+1=10

Представление целых чисел

Прямой код

Перейдем теперь к целым числам. В отличии от натуральных, целые числа могут быть также отрицательными. Например, – 5. У нас есть несколько возможностей для представления таких чисел. Мы можем использовать какой-то бит в качестве знака. Например, у нас есть 4 бита. Мы можем использовать первый бит для представления знака(0 – положительное число, 1 – отрицательное), а три оставшихся представляют само значение этого числа. 

 

 

0000

0

0001

1

0010

2

0011

3

0100

4

0101

5

0110

6

0111

7

1000

-0

1001

-1

1010

-2

1011

-3

1100

-4

1101

-5

1110

-6

1111

-7

Такой способ представления называется прямой код. Его достоинство заключается в удобстве для восприятия человеком. Но есть и недостатки. Во-первых, у нас две комбинации которые означают ноль. Во-вторых, если мы попробуем сложить две двоичных комбинаций, например -2+2, то получим 1010+0010=0110 = 12. Как видно, операции сложения с таким представлением не работают. Из-за этих недостатков подобный способ представления сегодня практически не используется.

Часовая арифметика

Что бы лучше понять способ представления, который актуален для современных компьютеров, рассмотрим такую вещь как часовая арифметика. Вспомните, как выглядят механические часы. У нас есть числа от одного до двенадцати, нанесенные по краям круга и стрелка, указывающая на какое-либо из них. Только представим, что в этих часах на месте где должно быть 12 – написано 0. Если сейчас одиннадцать часов, то сколько будет через 2 часа? Один час. В этом и заключается суть часовой арифметики – мы замкнуты в рамках этого числового круга и никогда не выходим за его пределы!  Что бы сложить два числа мы находим первое число на циферблате и относительно его по часовой стрелки делаем количество шагов, равное второму числу. Либо, что ведет к такому же результату, складываем значение двух чисел и отбрасываем 12. 9+6 будет три. Сколько будет  11+1? 0. В этом смысле мы можем сказать, что одиннадцать это как бы минус один, поскольку 11+1=0. 10 – это минус два, т.к. 10+2=0 и т.д. То есть мы можем условно выделить набор чисел (например от 6 до 11) и считать их отрицательными. 

11 = -1
10 = -2
9 = -3
8 = -4
7 = -5
6 = -6 

Ноль это ноль, а остальные числа от единицы до 5 - положительные.

Рассмотрим такой пример 1+10=11. Мы условились считать, что 10 это минус два, 11 –минус один. 1+ (-2) действительно равняется минус одному! Сколько будет 11+10? Если от 11 сделать десять шагов по часовой стрелки, то в итоге она будет указывать на 9. Либо можно посчитать так: 11+10=21. Отбрасываем 12 и получаем также 9.

-1 + -2 = -3 – похоже это и вправду работает!

Таким образом мы можем представлять и складывать отрицательные и положительные числа используя принципы часовой арифметики. Поскольку максимальное положительное число в данном примере равно 5, а отрицательное -6, то результат операции сложения не должен выходить за эти рамки. То есть мы можем сложить 2 и 3, но если сложить 3 и 3 мы получим 6, что является некорректным результатом т. к. 6 – это уже область отрицательных чисел. Но отрицательное число с положительным мы можем сложить в любом случае. Если использовать часы в которых, например, 100 значений, а не 12, то можно складывать уже более большие числа.

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

Рассмотрим теперь представление, называемое дополнительным кодом. Сначала на примере четырехбитных чисел. Мы поступаем также как и в предыдущем примере с часами, только чисел у нас тут не 12, а 16. Первую половину чисел - от нуля до 8 мы считаем натуральными, а числа от 8 до 15 – отрицательные.

15 (в двоичной системе – 1111) означает -1
14 (в двоичной системе – 1110) означает -2 и т.д. 

 

 

0000

0

0001

1

0010

2

0011

3

0100

4

0101

5

0110

6

0111

7

1000

-8

1001

-7

1010

-6

1011

-5

1100

-4

1101

-3

1110

-2

1111

-1

Удобно, что первая половина чисел начинается с нуля – а вторая с единицы. То есть если число начинается с нуля – оно натуральное, а если с единицы – оно отрицательное.

Можно еще скачать, что первая единица как бы означает -8. То есть 1000 = -8+0=-8,

1001 = –8+1 = -7, 1010 = -8+2 = -6 и т.д. Такое вот полезное наблюдение. Попытаемся теперь что-нибудь сложить. Например -6 + 5 = 1010+0101 = 1111 = -1. Получилось!

Еще один пример. -2 + 3 = 1110 + 0011 =  10001. Сходу кажется, что здесь какая-то ошибка, ведь числа 10001 нет в нашем списке. Но, вспомним часовую арифметику: там, если число превышало либо было равно 12, мы отбрасывали 12. В данном случае, поскольку чисел всего 16, нам необходимо отбросить 16. В двоичной системе это сделать очень легко – достаточно убрать последнюю единицу. Если это сделать, то получим число 0001 = 1. Все работает. Только нужно учитывать, что если в результате сложения мы получаем число, превышающее четыре бита, – последний бит необходимо отбросить.

И еще необходимо помнить, что при четырех битах результат операции сложение не должен быть больше чем 7 и меньше чем -8. Таким образом мы можем спокойно складывать числа друг с другом. Если необходимо выполнить операцию отрицания, мы можем представить ее как прибавление отрицательного числа. Например 6-5 = 6 + (-5) = 1 Как выполнить отрицание и перевести 5 в -5? Инвертировать биты и прибавить единицу. 5 это 0101. Инвертировать – это нули превратить в единицы, а единицы в нули.

Получается 1010. И теперь прибавляем единицу – получаем 1011.

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

ASCII код

Как можно представить символьную информацию с помощью битов, например, латинскую букву А? Напрямую никак, но можно создать некий код и договориться о его значении. Например, комбинация битов 01000001 будет означать A, 01000010 - B и т.д. Это и есть ASCII код – набор битовых паттернов, каждому из которых соответствует определенный символ. Нельзя сказать, что этот код является “естественным” для компьютера и что паттерн 01000001 каким-то образом происходит из буквы A. Это лишь результат договора: представители компьютерной индустрии собрались и путем обсуждений договорились какими битами можно обозначить тот или иной символ. Полную таблицу можно легко загуглить.