Ответ 1
Позвольте использовать случай, который вы найдете более знакомым: base 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 бит), не заботясь о том, что остальное количество или беспокоит двадцать шесть различных преобразований, когда мы можем это сделать один. Мы не могли бы выбрать вторую цифру, потому что вместо того, чтобы быть на 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-битной цифрой, здесь, в шестом столбце справа. Мы не могли бы использовать цифру в любом порядке справа (меньше), потому что тогда списки были бы перекрыты (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 в специальной системе основания 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-битное "byte" будет кодировать только 4 значения. Для передачи букв верхнего и нижнего регистра только одного алфавита потребуется 3 байта! В двоичном коде нет ничего, что заставляет выбирать 8 бит на байт, за исключением того, что 8 также является степенью 2, что делает большую часть математики более простой в работе с бинарной информацией, а вещи лучше выравниваются по краям. Если бы они выбрали 6 бит на байт, я уверен, что все получилось бы неловко и не использовало бы весь диапазон доступных значений.
Примечание 2: Моя система из пяти бит в 10 байт основана на нецелесообразности использования десяти 10 бит на байт, что дает действительно огромное количество, которое будет тратить много места на хранение. Я выбрал пять, потому что десять равномерно делится им, что, несомненно, было бы полезно. (Первоначально мой ответ использовал десять 10 бит на 10 байт, но он был слишком проклят большим!)