Двоичная арифметика
При программировании аппаратных средств важно уметь быстро переводить числа
из двоичной в восьмеричную или шестнадцатеричную системы и обратно. Чтобы
перевести двоичное число в восьмеричное, надо разбить его на группы по три бита,
начиная с наименее значащих, затем каждую группу по отдельности перевести в
восьмеричную цифру. Получившиеся восьмеричные цифры образуют запись исходного
числа в восьмеричной системе.
Примеры:
Чтобы перевести двоичное число в шестнадцатеричное, надо разбить его на группы
по четыре бита, начиная с наименее значащих, затем каждую группу по отдельности
перевести в шестнадцатеричную цифру. Получившиеся шестнадцатеричные цифры
образуют запись исходного числа в шестнадцатеричной системе.
Примеры:
|
hex | dec | oct | bin |
---|
0 1 2 3 4 5 6 7 8 9 A B C D E F |
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
0 1 2 3 4 5 6 7 10 11 12 13 14 15 16 17 |
0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111 |
|
Обратный перевод выполняется аналогично.
В двоичной арифметике используются следующие операции:
  | | Паскаль | Си |
побитовое отрицание (НЕ) | | NOT | ~ |
побитовое "И" | | AND | & |
побитовое "ИЛИ" | | OR | | |
побитовое исключающее "ИЛИ" | | XOR | ^ |
сдвиг влево | | SHL | << |
сдвиг вправо | | SHR | >> |
При побитовом отрицании в двоичном представлении числа каждый бит меняет
значение на противоположное.
Примеры:
0010 | 1110 |
|
1101 | 0001 |
NOT $2E = $D1
|
1000 | 1101 | 0011 | 1001 |
|
0111 | 0010 | 1100 | 0110 |
NOT $8D39 = $72C6
|
При побитовом "И" биты результата вычисляются по битам исходных чисел
независимо друг от друга. Единица получается только в том случае, если в
соответствующих разрядах исходных чисел обе единицы. В остальных случаях - ноль.
Примеры:
0010 | 1110 |
0011 | 0111 |
|
0010 | 0110 |
$2E AND $37 = $26
|
1000 | 1101 | 0011 | 1001 |
1010 | 0110 | 0100 | 1100 |
|
1000 | 0100 | 0000 | 1000 |
$8D39 AND $A64C = $8408
|
Побитовое "И" используется, чтобы определить значение определенного бита
числа. В этом случае в качестве второго операнда (маски) выбирают число, в
котором выставлен в 1 только интересующий разряд. В результате будет получен 0,
если в исходном числе интересующий разряд был равен 0. Если интересующий
разряд был равен 1, то результат выражения равен второму операнду.
xxxX | xxxx |
0001 | 0000 |
|
000X | 0000 |
a AND $10 = ?
|
xxxx | XXXX | xxxx | xxxx |
0000 | 1111 | 0000 | 0000 |
|
0000 | XXXX | 0000 | 0000 |
b AND $0F00 = ?
|
Побитовое "И" используется, чтобы сбросить в 0 определенные биты числа,
не меняя остальные. В этом случае в качестве второго операнда (маски) выбирают
число, в котором все биты, кроме битов, соответствующих сбрасываемым,
установлены в 1.
xxxx | xXxx |
1111 | 1011 |
|
xxxx | x0xx |
a := a AND $FD
|
xxxx | xxxx | XXxx | xxxx |
1111 | 1111 | 0011 | 1111 |
|
xxxx | xxxx | 00xx | xxxx |
b := b AND $FF3F
|
При побитовом "ИЛИ" биты результата вычисляются по битам исходных чисел
независимо друг от друга. Ноль получается только в том случае, если в
соответствующих разрядах исходных чисел оба нуля, в других случаях - единица.
Примеры:
0010 | 1110 |
0011 | 0111 |
|
0011 | 1111 |
$2E OR $37 = $3F
|
1000 | 1101 | 0011 | 1001 |
1010 | 0110 | 0100 | 1100 |
|
1010 | 1111 | 0111 | 1101 |
$8D39 OR $A64C = $AF7D
|
Побитовое "ИЛИ" используется, чтобы установить в 1 определенный бит числа,
не меняя остальные. В этом случае в качестве второго операнда (маски) выбирают
число, в котором выставлен в 1 только интересующий бит, а остальные сброшены.
Xxxx | xxxx |
1000 | 0000 |
|
1xxx | xxxx |
a := a OR $80
|
XXXx | xxxx | xxxx | xxxx |
1110 | 0000 | 0000 | 0000 |
|
111x | xxxx | xxxx | xxxx |
b := b OR $E000
|
Побитовое исключающее "ИЛИ" отличается от обычного "ИЛИ" тем, что два
единичных бита дают в результате этой операции 0.
Примеры:
0010 | 1110 |
0011 | 0111 |
|
0001 | 1001 |
$2E XOR $37 = $19
|
1000 | 1101 | 0011 | 1001 |
1010 | 0110 | 0100 | 1100 |
|
0010 | 1011 | 0111 | 0101 |
$8D39 XOR $A64C = $2D75
|
Побитовое исключающее "ИЛИ" используется, чтобы изменить определенный бит
числа (инвертировать), не меняя остальные. В этом случае в качестве второго
операнда (маски) выбирают число, в котором выставлен в 1 только интересующий
бит, а остальные сброшены.
xxxx | xxXx |
0000 | 0010 |
|
xxxx | xxYx |
a := a XOR $02
|
xxxx | xxxx | xxxx | XXXX |
0000 | 0000 | 0000 | 1111 |
|
xxxx | xxxx | xxxx | YYYY |
b := b XOR $000F
|
При побитовом сдвиге влево на 1 разряд в двоичной записи первого аргумента
справа добавляется 0, а выходящий за разрядную сетку старший бит отбрасывается.
Второй аргумент операции сдвига задает, сколько раз необходимо проделать такую
процедуру. Сдвиг влево на n бит эквивалентен умножению числа на 2n и
имеет то преимущество, что вычисляется процессором гораздо быстрее, чем
целочисленное умножение.
Примеры:
0010 | 1110 |
SHL 1 |
|
0101 | 1100 |
$2E SHL 1 = $5C
|
1000 | 1101 | 0011 | 1001 |
SHL 3 |
|
0110 | 1001 | 1100 | 1000 |
$8D39 SHL 3 = $69C8
|
Сдвиг влево используют, чтобы "собрать" многобайтное число из отдельных
байтов. Например:
$78 + $56 SHL 8 + $34 SHL 16 + $12 SHL 24 = $12345678
Различают два типа побитовых сдвигов вправо: арифметический и логический.
При арифметическом сдвиге вправо на 1 разряд в двоичной записи первого
аргумента слева дублируется старший разряд (бит знака), а младший бит числа
отбрасывается. При логическом сдвиге вправо на 1 разряд в двоичной записи
первого аргумента слева добавляется 0, а младший бит числа отбрасывается.
Второй аргумент операции сдвига задает, сколько раз необходимо проделать такую
процедуру. Арифметический сдвиг вправо на n бит эквивалентен делению числа
на 2n с учетом знака, а логический - беззнаковому делению. В Паскале
используется логический сдвиг, а в Си - арифметический.
Примеры:
0010 | 1110 |
SHR 1 |
|
0001 | 0111 |
$2E SHR 1 = $17
|
1000 | 1101 | 0011 | 1001 |
(логический) SHR 2 |
|
0010 | 0011 | 0100 | 1110 |
$8D39 SHR 2 = $234E
|
1000 | 1101 | 0011 | 1001 |
(арифметический) >> 2 |
|
1110 | 0011 | 0100 | 1110 |
-29383 >> 2 = -7346
|
Совместно с побитовым "И" сдвиг вправо используют, чтобы "разобрать"
многобайтное число на отдельные байты. Например:
$12345678 AND $000000FF = $78
$12345678 AND $0000FF00 SHR 8 = $56
$12345678 AND $00FF0000 SHR 16 = $34
$12345678 AND $FF000000 SHR 24 = $12