Мы живём в десятичной (decimal, DEC) системе счисления - любое число в ней можно представить десятью цифрами - от 0
до 9
. Процессор же - цифровое устройство, то есть может оперировать только двумя величинами: 0
и 1
, правда и ложь, высокий сигнал и низкий. Такая система счисления называется двоичной или бинарной (binary, BIN). Вся работа и процессор в целом построены на двоичной логике и многие моменты в программировании тоже на этом завязаны.
Единицы измерения информации #
Единица измерения цифровой информации, которая имеет только два состояния, называется бит (bit). Соответственно элементарная ячейка памяти, с которой процессор может взаимодействовать - один бит. Как и в других единицах измерения, в цифровых величинах существуют приставки для упрощения счёта больших чисел (метр, сантиметр, километр...), но работают они с другими множителями. Следующая после бита единица измерения - байт (byte) - содержит 8 бит. Так сложилось исторически по ряду причин и в большинстве современных систем используется именно 8-битный байт:
- Процессор работает с двоичными данными, поэтому аппаратно проще и удобнее реализовать адресацию по степени двойки, то есть числа 2, 4, 8, 16, 32...
- 8 бит (256 значений) достаточно для хранения символа из стандартной таблицы символов
Следующие по объёму единицы измерения имеют привычные приставки кило-мега-гига-тера, но множитель у них - 1024
, что привело к путанице с привычным множителем 1000
. В 1999 году Международная электротехническая комиссия (МЭК) ввела стандарт по именованию двоичных чисел, который предписывает считать множителями двоичных чисел кило-мега-гига-тера именно 1000
. Для двоичных чисел были придуманы специальные приставки: киби-меби-гиби-теби с множителем 1024
. Помимо величин с окончанием байт также есть вариант с окончанием бит, то есть указывает непосредственно на количество бит информации.
Таблицы с величинами
Название | Объём |
---|---|
Килобайт, Кбайт, КБ (KByte, KB) | 1000 Байт, 10^3 Байт |
Мегабайт, Мбайт, МБ (MByte, MB) | 1000 Кбайт, 10^6 Байт |
Гигабайт, Гбайт, ГБ (GByte, GB) | 1000 Мбайт, 10^9 Байт |
Терабайт, Тбайт, ТБ (TByte, TB) | 1000 Гбайт, 10^12 Байт |
Название | Объём |
---|---|
Кибибайт, КиБ (KiB) | 1024 Байт, 2^10 Байт |
Мебибайт, МиБ (MiB) | 1024 КиБ, 2^20 Байт |
Гибибайт, ГиБ (GiB) | 1024 МиБ, 2^30 Байт |
Тебибайт, ТиБ (TiB) | 1024 ГиБ, 2^40 Байт |
Название | Объём |
---|---|
Килобит, кбит (kbit) | 10^3 бит |
Мегабит, Мбит (Mbit) | 10^6 бит |
Гигабит, Гбит (Gbit) | 10^9 бит |
Терабит, Тбит (Tbit) | 10^12 бит |
Название | Объём |
---|---|
Кибибит, Кибит (Kibit) | 1024 бит, 2^10 бит |
Мебибит, Мибит (Mibit) | 1024 Кибит, 2^20 бит |
Гибибит, Гибит (Gibit) | 1024 Мибит, 2^30 бит |
Тебибит, Тибит (Tibit) | 1024 Гибит, 2^40 бит |
В то же время в Российском стандарте от 2009 года принято использование множителя 1024
со стандартными приставками, то есть:
- 1 Кбайт = 1024 байт
- 1 Мбайт = 1024 Кбайт
- 1 Гбайт = 1024 Мбайт
- 1 Тбайт = 1024 Гбайт
Таким образом для определения точного объёма информации необходимо учитывать контекст.
Двоичная система #
Если считать числа по порядку в любой системе счисления с шагом в 1, то, когда младший разряд достигает своего максимального значения - он становится 0
, а старший для него разряд получает +1
. Так, например, десятичное число 19
превращается в 20
после прибавления единицы - 9
становится нулём 0
, а единица 1
прибавляется к следующему разряду и получается 2
. Давайте посчитаем числа по порядку в десятичной и двоичной системах:
DEC | BIN |
---|---|
0 | 0000 |
1 | 0001 |
2 | 0010 |
3 | 0011 |
4 | 0100 |
5 | 0101 |
6 | 0110 |
7 | 0111 |
8 | 1000 |
9 | 1001 |
… | … |
16 | 10000 |
Заметили последовательность?
Также здесь можно заметить особенность степени двойки - на ней в программировании завязано очень многое. Давайте посмотрим отдельно на первые 8 степеней двойки:
2^ | DEC | BIN |
---|---|---|
0 | 1 | 00000001 |
1 | 2 | 00000010 |
2 | 4 | 00000100 |
3 | 8 | 00001000 |
4 | 16 | 00010000 |
5 | 32 | 00100000 |
6 | 64 | 01000000 |
7 | 128 | 10000000 |
Таким образом, степень двойки "указывает" на порядковый номер бита. Это можно использовать для перевода чисел из двоичной системы в десятичную - достаточно заменить каждую единичку на соответствующее ей значение и все их сложить. Например 1001
- это 2^3 + 2^0 = 8 + 1 = 9.
MSB и LSB #
Как и в любой другой системе счисления, у чисел в двоичной системе есть разряды. В жизни мы записываем числа слева направо, от старшего к младшему, то есть у десятичного числа 123
старшим разрядом будет 1
, а младшим - 3
. То же самое - с двоичным, для краткости самый младший разряд называется LSB (Least Significant Bit), а самый старший - MSB (Most Significant Bit): MSB
-> 1001
<- LSB
.
Эти обозначения довольно часто встречаются при работе с хранением и передачей данных: данные читаются и передаются по одному биту по порядку, но направление может быть разным! Если передача начинается со старшего бита - она называется MSB first (сначала MSB), если с младшего - LSB first (сначала LSB)
Другие системы счисления #
Система счисления может иметь любое основание, то есть можно представить себе троичную, пятеричную и любые другие системы.
Данные в памяти микроконтроллера хранятся в двоичном представлении, но компилятор поддерживает и другие системы, в которых мы можем работать - десятичная (DEC), восьмеричная (octal, OCT) и шестнадцатеричная (hexadecimal, HEX). У систем счисления, отличных от десятичной, при записи чисел в коде программы требуется префикс - чтобы компилятор понимал, о чём идёт речь:
Основание | Префикс | Значения | Пример |
---|---|---|---|
2 (BIN) | 0b |
0-1 | 0b0101001 |
8 (OCT) | 0 (ноль) |
0–7 | 0175 |
10 (DEC) | нет | 0-9 | 100500 |
16 (HEX) | 0x |
0-9, буквы A-F и a-f | 0x0FF21A |
Переводить числа из одной системы счисления в другую не нужно - компилятор сделает это сам.
// одно и то же число
0b010011010010; // BIN
1234; // DEC
02322; // OCT
0x4D2; // HEX
Поддержка разных систем счисления нужна просто для удобства программиста:
- Привычные
DEC
числа мы будем использовать для обычных "человеческих" математических операций HEX
числами принято записывать цвет, адреса в памяти, а также всякие ключи шифрования, хэши и прочие численные коды - HEX визуально занимает меньше места и уже выглядит как код. Ещё одно большое преимущество HEX - два соседних разряда занимают 1 байт, то есть визуально можно оценить размер числа и увидеть значение каждого байта в нём. Например0x12ab
- это два байта со значениями0x12
и0xab
BIN
числа удобно использовать для манипуляций с битами в числе, работы с регистрами и создания алгоритмов на базе битовой математикиOCT
чисел на практике не встречал
Значащие нули #
Значащие нули – это нули, которые нельзя убрать из числа, иначе получится другое число. Например если из числа 1230
убрать правый ноль - оно уменьшится в 10 раз. По сути это крайние младшие разряды, находящиеся справа. Незначащие нули можно убрать или добавить к числу слева (сразу после префикса, если он имеется) - число от этого не изменится: если из числа 0b0011
убрать левый ноль - его значение останется 0b011
, можно и второй ноль убрать - 0b11
- это всё ещё то же число. В предыдущих таблицах я добавил незначащих нулей числам в столбце BIN, чтобы выровнять их по количеству разрядов для наглядности.
Таким образом восьмеричная система - это ловушка Джокера. У числа есть незначащий ноль, убирать который нельзя!
Основные тезисы урока #
- Процессор работает с двоичными числами, для него существуют только единицы и нули
- В двоичной системе любое число может быть представлено цифрами 0 и 1
- Бит - минимальная единица измерения цифровой информации, может принимать только два значения - 0 и 1
- Байт состоит из 8 бит
- Многое в программировании завязано на значениях степени числа 2, т.к. процессор спроектирован таким образом
- У числа в двоичной системе самый старший бит называется MSB, самый младшй - LSB
- Компилятор C/C++ поддерживает числа в двоичной системе с префиксом 0b, восьмеричной с префиксом 0, десятичной без префикса и шестнадцатеричной с префиксом 0x
- Поддержка разных систем счисления нужна для удобства, компилятор сам переведёт всё в нужный формат
- Значащие нули находятся справа от числа, их убирать нельзя. Незначащие нули можно добавить к числу слева для нужд форматирования, они не меняют само число