Еще в школьные годы мы привыкли считать 0, 1, 2..9 ... и мы ссылались на десятичную систему счисления с основанием 10, состоящую из 10 цифр. Любое число может быть образовано с использованием степеней 10. Например, 125 это:

Это то, что мы использовали до сих пор. Но тогда что такое 0 и 1. Почему 0 и 1? Наши компьютеры - это электрические устройства, которые понимают, включено или выключено. Мы следуем двоичной системе, состоящей из двух цифр 0 и 1, чтобы общаться с ними. Пусть это будет текст, изображение или число, в мозгу компьютера все равно 0 и 1. То же самое и для двоичного кода, используя базу 2, мы можем фактически декодировать число. Например, Что означает 1001 в двоичном формате? Это число 9.

Основные правила сложения и вычитания двоичных чисел:
На самом деле это не правила, а лишь некоторые воспоминания о сложении и вычитании в нашем третьем классе. Принесите мне базовые концепции, и тогда мы поднимемся на удивительные вещи.
1 + 0 = 1;
0 + 0 = 0;
0 + 1 = 1;
1 + 1 = 10 напишите 0 и перенесите 1 на место 2;
Мы все знаем, что 1 + 1 равно 2. Также 2 - это не что иное, как 10 в двоичном формате. Если бы у нас было 19 в десятичном сложении, что бы мы делали? Напишите 9 и перенесите единицу в разряд десятков? Аналогично здесь мы пишем 0 и несем единицу. Прохладный? Теперь посмотрим на вычитание двоичных цифр:
0–0 = 0;
1–0 = 1;
1–1 = 0;
0–1 = 1 путем заимствования 2;
Вот как это происходит:

Итак, это было все о базовом двоичном коде и его арифметике. Но как все эти 1 и 0 хранятся в компьютере? В оперативной памяти компьютера существует столько адресов, которые выделяются для разных типов данных, по мере того, как мы их создаем. Здесь мы сосредоточимся только на целочисленном типе. Один 0 или один 1 называется битом. 8 бит состоят из 1 байта. Каждому байту дается собственный адрес. Размер целого числа в Java фиксирован, в отличие от C ++, который зависит от машины, это 4 байта, то есть 32 бита. Теперь давайте посмотрим на нашу переменную на гипотетической диаграмме памяти:

Теперь предположим, что значение a равно 2555. Таким образом, единицы и нули сохраняются в 32-битном целом числе. Предположим, что горизонтальное представление

Когда младший бит занимает младший адрес, он называется Little Endian, а когда младший бит занимает старший адрес, это называется Big Endian представлением.

Теперь, если это int, я могу хранить любое целочисленное значение, не так ли? Ответ - нет, потому что каждый тип данных имеет определенный диапазон. Как теперь определяется этот диапазон?
Если у нас есть один бит, мы можем иметь 2 значения: 0 или 1.

Здесь мы замечаем, что при наличии n битов возможно возведение 2 до n значений. Диапазон значений от 0 до (2 ^ n -1). В качестве примера см. Пример с 3-мя битами .. значения сверху вниз в десятичном виде от 0 до 7, то есть от 0 до
(8–1).
Так как int имеет 32 бита .. от 0 до Возможны значения (2³²-1).

Однако есть одна проблема: таким образом мы не можем включать отрицательные числа! Есть ли способ представить отрицательные числа? Первое, что пришло мне в голову, это почему я не могу добавить знак «-» перед числом, как мы это делаем в десятичной системе счисления. Почему - (001) не может представлять -1? Проблема здесь в том, что компьютер не понимает '-' ... он знает только 0 и 1.
Что, если бы мы сделали самый старший бит как бит знака, а остальные биты как биты величины? 0 число положительное, а если 1 - отрицательное. См. Пример с 3 битами выше. Первые четыре числа будут считаться положительными, а последние четыре числа - отрицательными, как показано ниже:

Здесь есть две проблемы:
1. 0 встречается два раза.
2. Арифметическое вычитание не имеет смысла в двоичном формате. В качестве действия попробуйте
001 + 101. Получили 0? Без прав? Что-то не так с этим соглашением. 1 + (-1) должен давать 0, но, используя двоичные числа и арифметику, мы получили -2!

Что же нам делать, чтобы также представлять отрицательные числа? Лучше всего использовать метод дополнения до 2. Отрицательное двоичное число хранится как дополнение до 2. Он говорит, что нужно найти отрицательное значение любого числа:
a. Инвертируйте число (0 меняется на 1 и наоборот)
b. Добавьте к нему единицу.
Изюминка в том, что когда вы добавляете число и его дополнение до 2, вы получаете 0, то есть мы можем выполнять обычную двоичную арифметику.
Двойное дополнение к 001:
a . Инвертировать: 110
b. Добавьте один: 111

Все будет выглядеть так, когда мы воспользуемся дополнением до 2.

В этой системе старший бит отрицательного числа также равен 1. Не запутайтесь, преобразовав вышеуказанные отрицательные двоичные числа в десятичные и просто добавив отрицательный знак, это не так, как это работает. При оценке числа возьмите отрицательный знак только с термином MSB и добавьте к нему все остальные термины. Например:

Теперь мы можем оценить диапазон. Для 3-х битов диапазон составляет (от -4 до 3), то есть (от -2² до 2²-1). Таким образом, мы видим, что для n бит диапазон составляет
(-2 ^ (n-1) до 2 ^ (n-1) -1).

А теперь, неужели вы не задумывались над вопросом «ПОЧЕМУ?», Читая правила дополнения до двух? Что ж, это аналогия, которую я однажды прочитал:

Всякий раз, когда мы находим отрицательное число, мы в основном вычитаем это число из 0. Рассмотрим число 12 в 8 битах. Это двоичное представление 00001100. Чтобы найти отрицательный результат, мы выходим на 12 шагов дальше 0.

Компьютер считает только восемь битов и отбрасывает все остальное. В приведенном выше примере ноль в MSB также заимствован, но поскольку наша машина считает 8 бит, это не имеет значения. Вычитание восьми (n) битового числа из 0 эквивалентно вычитанию его из 100000000, то есть 1, за которым следуют 8 нулей (n 0) или 2⁸ (2 ^ n). 100000000 эквивалентно (11111111 + 1)

Итак, что мы наконец делаем ...
11111111 + 00000001–00001100 (число)
А в двоичной системе вычитание числа из числа, все биты которого равны 1, эквивалентно инвертированию битов этого числа. Попробуйте это как занятие.
И это то, что мы делаем как ярлык. Инвертируем биты и добавляем единицу.
Спасибо за чтение.