Этот урок является одним из самых сложных уроков для новичков. Но почему же? Это объясняется тем, что надо вникнуть не только в язык программирования, а и в новую систему счисления. Если Вы уже знакомы с двоичной системой, то можете пропустить первую часть урока.
Как нам известно, каждая система счисления имеет базис. Например, в десятеричной, которой мы пользуемся ежедневно, базис – 10. И каждое число мы можем представить в виде a*10 + b*10^2 + … + x*10^n. В двоичной системе счисления все точно так же, но с числом 2. Давайте попробуем представить число 123 в десятеричной системе.
123 = 3 * 10^0 + 2 * 10 + 1 * 10^2
Но как же будет выглядеть число 123 в двоичной системе? Для этого воспользуемся простым алгоритмом. Возьмём число, которое является степенью двойки, меньше заданного нам числа и наиболее приближено к нему. В нашем случае это чисто 64. Теперь вычитаем от нашего числа 64 и получим 59. Теперь смотрим, сможем ли мы вычесть от этого числа меньшую степень двойки – число 32. Можем, поэтому вычитаем и получим 27. И так далее, пока у нас не останется 0. Итак, от числа 123 мы вычитали числа 64, 32, 16, 8, 2 и 1. Напоминаю, что любое число в нулевой степени – 1. Заметим, что от нашего числа мы не вычитали 4. Теперь нужно задаться вопросом: «Какие степени двойки мы вычитали?». Это были степени 6, 5, 4, 3, 1 и 0. Если написать на их месте единички, а на всех остальных – нолики, то получим число 1111011. Это и есть число 123, но в двоичной системе.
Как известно, любая цифра в любой системе счисления не может превышать её базис.
Отлично, мы теперь разобрались с двоичной системой счисления. Но почему именно она выбрана для компьютеров? Это потому, что компьютеры полностью построены на логических командах. Их всего две: true и false, или есть сигнал и нету сигнала соответственно. Если сигнал есть, получаем 1, если нет – 0.
Как и с обычными логическими переменными, мы можем выполнять те же операции и с числами. Вы спросите: «Как это? Логические операции мы выполняем только с переменными логического типа!» Но и обычные числа тоже можно «сделать логическими». Для этого любое число переводится в двоичную систему. А ведь каждый знак этого числа и есть логической переменной. Это не значит, что мы сможем «вытянуть» любой знак числа и использовать в программе как логическую переменную, а просто все операции будут выполняться соответственно с операциями булевского типа.
Думаю, хватит разговоров. Переходим к практике.
Вы ещё не успели забыть логические операторы &&, ||, ! И ^. Давайте же переделаем одну из логических операций на побитовую. Допустим, это будет операция И. Но она обозначается не двумя знаками &, а только одним. Бит – малейшая частичка кодирования, 1/8 байта. Каждая цифра в двоичной системе счисления – один бит. Итак, рассмотрим все побитовые операторы на примере чисел 10 и 7.
| Выражение | Значение | Объяснение |
|---|---|---|
| 10 & 7 | 2 | В двоичной системе число 10 имеет вид 1010, а число 7 – 0111. Проводя операцию логического И с этими числами, получим число 0010, что в десятеричной системе – 2 |
| 10 | 7 | 15 | Здесь используется тот же принцип, только с операцией логического ИЛИ. Получаем число 1111 |
| 10 ^ 7 | 13 | Оператор ^ - это оператор исключающего ИЛИ. То есть если два сравниваемых значения одинаковы, то результат равен 0, то есть false, если разные – true, иначе говоря - 1. В результате выполнения 10 ^ 7 получим число 1101, то есть 13 |
| ~10 | -11 | Данная операция отличается от всех остальных тем, что она унарная. Особенности этого оператора мы рассмотрим после таблички |
| 10 >> 3 | 1 | Оператор сдвига вправо сдвигает все биты числа вправо. При этом все биты, которые оказываются за границей байта просто отпадают, а освободившееся место в конце бита (если считать за конец бита ту часть, где степень двойки больше) забивается нулями |
| 10 << 3 | 80 | В данном случае происходит все тоже самое, но в обратном направлении |
Итак, мы рассмотрели в данной таблице все побитовые операторы. Но кое-какие мы так полностью и не выучили. Это оператор ~, который переводит все биты числа в противоположные. Но в данном случае нам ничего не говорит, что число стало отрицательное, но это всегда так. Компьютер знает, что это число – отрицательное. Если мы будем вникать в природу представления отрицательного числа компьютером, то этот урок будет длиться несколько часов
Но, как мы видим, при операции ~а, где а – произвольно число стандартного типа, мы получаем число –(а + 1). Поэтому, для того, чтобы получить число, противоположное данному, надо всего лишь написать ~а+1, где а снова играет роль любого числа базового типа. Попробуйте проделать это самостоятельно.
Правоохранительные органы, всевозможные организации, государственные учреждения – все они используют шифровку данных. Конечно, можно придумать всевозможные алгоритмы шифрования, но один из них является самым простым и не каждый сможет его быстро разгадать. Давайте рассмотрим числа (в двоичной системе) 10011101 и 11110001. Выполним операцию исключающего ИЛИ с этими числами. Получим число 01101100. Но что будет, если мы снова выполним операцию ^ нашего результата со вторым числом? Мы получим число 10011101, что и есть нашим начальном числом. Круто, не правда ли?