Давайте использовать случай, который вы найдете более знакомым: база 10.
Предположим, у нас есть базовый 10 компьютер, где каждый 10-битный хранит значение от 0 до 9, а 10-байтовый имеет длину 5 10 бит, так что каждый байт может хранить 100 000 значений (от 0 до 99 999).
Вы хотите назначить буквы определенным позициям в 10 байт, чтобы этот компьютер мог обмениваться текстовыми данными с другими компьютерами. Один из способов сделать это было бы так:
00101 A 00201 a
00102 B 00202 b
00103 C 00203 c
00104 D 00204 d
00105 E 00205 e
00106 F 00206 f
00107 G 00207 g
00108 H 00208 h
00109 I 00209 i
00110 J 00210 j
00111 K 00211 k
00112 L 00212 l
00113 M 00213 m
00114 N 00214 n
00115 O 00215 o
00116 P 00216 p
00117 Q 00217 q
00118 R 00218 r
00119 S 00219 s
00120 T 00220 t
00121 U 00221 u
00122 V 00222 v
00123 W 00223 w
00124 X 00224 x
00125 Y 00225 y
00126 Z 00226 z
Видите ли вы, что каждая строчная буква отличается от заглавной буквы только одной 10-битной цифрой в 3-м столбце справа? Он не должен был проектироваться таким образом. Это было просто удобно, потому что в любое время, когда мы хотим изменить регистр букв, мы можем просто изменить одну из цифр (10 бит), не заботясь о том, что представляет собой остальная часть числа, или не беспокоиться о двадцати шести различных преобразованиях, когда мы можем сделать один . Мы не могли бы выбрать вторую цифру, потому что вместо 100, они были бы только 10 и перекрывались.
Теперь в базе 2 он точно такой же, но вместо каждого бита, представляющего 0-9, он может представлять только 0-1. Использование восьми 2-битных дает нам только 256 возможных комбинаций, 0-255. Коды ASCII для букв верхнего и нижнего регистра в двоичном виде выглядят так:
01000001 A 01100001 a
01000010 B 01100010 b
01000011 C 01100011 c
01000100 D 01100100 d
01000101 E 01100101 e
01000110 F 01100110 f
01000111 G 01100111 g
01001000 H 01101000 h
01001001 I 01101001 i
01001010 J 01101010 j
01001011 K 01101011 k
01001100 L 01101100 l
01001101 M 01101101 m
01001110 N 01101110 n
01001111 O 01101111 o
01010000 P 01110000 p
01010001 Q 01110001 q
01010010 R 01110010 r
01010011 S 01110011 s
01010100 T 01110100 t
01010101 U 01110101 u
01010110 V 01110110 v
01010111 W 01110111 w
01011000 X 01111000 x
01011001 Y 01111001 y
01011010 Z 01111010 z
Так же, как и раньше, они отличаются только одной 2-битной цифрой, здесь, в 6-м столбце справа. Мы не могли бы использовать цифру чуть правее (меньше), потому что тогда списки перекрывались бы (2 ^ 5 = 32, и соответственно мы использовали все биты с 0 по 5, но 2 ^ 4 = 16, что не могло охватывать 26 букв алфавита).
Просто для небольшого пояснения, вот пример того, что означают эти двоичные значения. Давайте возьмем один для G. Чтобы понять, что означает 01000111 в двоичном виде:
Pos: 7 6 5 4 3 2 1 0
Bit: 0 1 0 0 0 1 1 1
Val: 128 64 32 16 8 4 2 1
Mult: 0 64 0 0 0 4 2 1
Add: 64 + 4 + 2 + 1 = 71, which is the ASCII code for G.
То же самое для буквы G в специальной системе Base 10, которую я построил выше:
Pos: 4 3 2 1 0
10Bit: 0 0 1 0 7
Val: 10000 1000 100 10 1
Mult: 0 0 100 0 7
Add: 100 + 7 = 107, which is my special 10ASCII code for G.
Посмотрите на строку "Val" для двоичного файла. Вы видите, что, начиная справа, каждое значение вдвое больше предыдущего? Удваивая каждый раз, мы получаем 1, 2, 4, 8, 16, 32, 64, 128, 256, 512 и так далее. Вот как позиция двоичной цифры определяет ее значение, точно так же, как позиция десятичной цифры определяет ее значение с степенями 10: 1, 10, 100, 1000, 10000, 100000 и т. Д.
Я понимаю, что это кажется глупым, потому что все, что я сделал, это преобразовал 107 в 107 ... но 107 это не просто число, это сокращенная форма для:
1 hundreds + 0 tens + 7 ones.
Другой способ, которым мы могли бы представить, это
0 x 10^4 + 0 x 10^3 + 1 x 10^2 + 0 x 10^1 + 7 x 10^0.
Аналогично, 01000111 - это не просто двоичное число, это сокращенная форма для
0 x 2^7 + 1 x 2^6 + 0 x 2^5 + 0 x 2^4 + 0 x 2^3 + 1 x 2^2 + 1 x 2^1 + 1 x 2^0
То, что я вам уже показал:
0 + 64 + 0 + 0 + 0 + 4 + 2 + 1
= 64 + 4 + 2 + 1
= 71
Кроме того, вы, возможно, задавались вопросом, что означают 0x41
и 0x61
. Часть 0x
указывает на то, что следующие цифры следует понимать как шестнадцатеричные, то есть основание 16. В нашей системе счисления всего 10 цифр, поэтому нам нужно как-то еще 6 цифр. Таким образом, шестнадцатеричное число использует цифры 0-9 и рассматривает буквы AF как оставшиеся цифры, где A - от 10 до F как 15. Шестнадцатеричное очень удобно для компьютеров, поскольку 16 - это степень 2, а 8-битный байт, таким образом, для кодирования требуется ровно две шестнадцатеричные цифры (и каждая шестнадцатеричная цифра кодирует ровно четыре двоичных цифры). Взяв 0x41
, расширив 4
до его двоичного представления 0100
и расширив 1
до его двоичного представления 0001
, вы получите 01000001
, который, как вы видите, представляет собой код для A
, как показано. Чтобы преобразовать его в десятичную, это 4 x 16 + 1 x 1 = 65. Мы умножаем 4 на 16, потому что каждая последующая шестнадцатеричная цифра влево в 16 раз превосходит предыдущую цифру, следуя той же схеме, что я показал вам выше для оснований 2 и 10. .
Надеюсь, этого будет достаточно, чтобы вы поняли немного больше о двоичных кодах и кодах ASCII.
Примечание 1: Причина в 8 битах в байте вместо 2, как вы могли бы подумать, заключается в том, что еще в первые дни вычислений было решено, что 8 является гораздо более полезным числом битов2-битный «байт» будет кодировать только 4 значения.Для передачи только прописных и строчных букв алфавита потребуется 3 байта!В двоичном коде нет ничего, что заставляло бы выбирать 8 бит на байт, за исключением того, что 8 также является степенью 2, что упрощает большую часть математики, связанной с работой с двоичной информацией, и лучше выравнивает края.Если бы они выбрали 6 бит на байт, я уверен, что все получилось бы неловко, и не использовал бы весь диапазон доступных значений.
Примечание 2: Моя система из пяти бит в 10 байт основана на непрактичности использования десяти 10 бит на байт, что дает действительно огромное число, которое потратило бы много места для хранения.Я выбрал пять, потому что десять делится на него поровну, что, несомненно, будет полезно.(Первоначально, мой ответ использовал десять 10 бит на 10 байт, но он был слишком чертовски большим!)