Я походу разобрался с прямым кодом, обратным кодом и дополнительным кодом. Кому интересно:
Короче говоря, в восьмибитной системе числа определяются восемью ячейками:
00000000
. Это будет ноль. Чтобы получить единицу, надо прибавить 1 в самый конец: 00000001
. Чтобы получить двойку, надо прибавить ещё 1 (разумно). Но тут самое интересное. Т.к. мы в двоичной системе, а не в десятичной, то здесь после прибавление 1 будет не 00000002
, а 00000010
, т.е. мы перейдём в следующий разряд. Соответственно число 3, будет 00000011
, а число 4 уже 00000100
, т.к. мы опять перешли в следующий разряд.
Далее, как работает сложение в двоичном коде: очень просто. Берём два числа, например 64 01000000
и 6 00000110
. Чтобы их сложить, просто берём и складываем столбиком, как учили в школе:
01000000
00000110
01000110
Можете проверить, двоичное число 01000110
соответствует 70. Если при сложении у вас в одном разряде получилось две 1, то переходите в следующий разряд, если и там получилось две 1, то дальше, и так бесконечно. Если 1 вышла за границу 8 разряда, то просто отбрасываете её: в данном случае вы скорее всего получили число, которое не попадает в диапазон -128...127.
Теперь поговорим про отрицательные числа. Для простоты архитектуры ЭВМ, отрицательные числа представлены всегда в виде дополнительного кода, т.е. следующим образом: берёте, например любое положительное число (возьмём 6, которая в двоичном коде отображается как
00000110
. Получаем из положительной 6 обратный код, т.е. меняем все 0 на 1, а все 1 на 0, получаем:
11111001
. Теперь из этого кода получаем дополнительный код, т.е. добавляем к данному коду 1 (как было показано выше):
11111001
00000001
11111010
Код
11111010
является дополнительным кодом числа -6. При операциях в ЭВМ всегда используется именно он.
Давайте теперь попробуем сложить -6
11111010
и 7
00000111
. С точки зрения ЭВМ, это именно сложение -6 и 7, а не вычитание 6 из 7. Складываем их так же, как складывали все числа ранее:
11111010
00000111
100000001
Смотрите, получившийся двоичный код
100000001
вмещает в себя 9 ячеек, тогда как в восьмибитной системе может быть только 8. Соответственно, чтобы впихнуть этот код в 8 бит, убираем самую первую 1. Получаем
00000001
, что в переводе с двоичного кода в десятичный будет равно 1. Итак, ответ на пример (7 + (-6)) = 1. Правильно? Правильно!
А ещё тут же можно понять, почему диапазон значений в восьмибитной системе -128...127. Число 127 имеет такой вид в двоичной записи
01111111
и это максимально возможное число в 8 битах. Потому что в 8-битной системе самая первая ячейка означает положительно ли число или отрицательно. 0 - число положительное, 1 - число отрицательное. И когда вы хотите сделать из 127 128 путём прибавление 1, получается так:
01111111
00000001
10000000
8-битная система, подразумевает, что раз первым числом идёт 1, то это число отрицательное. А раз оно отрицательное, то этот код - дополнительный. А дополнительный код
10000000
соответствует числу -128 и помещается в восемь битов. Была бы система у нас 16-битная, то мы бы спокойно получили 128. Но первая ячейка всегда означает положительность или отрицательность числа, и, соответственно, машина думает, что раз первая ячейка - 1, то этот код дополнительный.