В этой статье рассматриваются бинарные операторы PHP и способы преобразования между различными системами подсчета. Большинство книг и статей по программированию посвящают только одну или две страницы таким темам, и хотя использование операторов действительно довольно просто, существует достаточное количество базовых знаний, которые необходимо использовать, чтобы правильно их использовать.
Вместо того, чтобы давать то же самое лечение, которое дает любая другая ссылка, я сначала предоставлю вам необходимые знания в теории чисел. Вооружившись этими знаниями, вы сможете понять двоичную систему подсчета и базовые преобразования… и знакомство с двоичными цифрами является ключом к успешному использованию бинарных операторов! Итак, без дальнейших задержек, давайте начнем!
Теория чисел
Систему подсчета, с которой мы все знакомы, можно представить как серию пакетов и контейнеров. Каждый пакет стоит одну единицу и упакован вместе с другими пакетами и помещен в соответствующий контейнер. Каждый контейнер может содержать только определенное количество единиц, и эти единицы должны быть упакованы в соответствующие пакеты для этого контейнера.
В нашей системе подсчета Base-10 единицы связаны в кратные числа 10. Это означает, что у нас может быть до девяти единичных единиц, но после добавления десятой единицы все они должны быть упакованы вместе, чтобы составить единый пакет.
Там нет никаких сюрпризов, но магия лежит в контейнерах. Давайте разместим ряд ковшей рядом и ограничимся заполнением только самых правых контейнеров. Как только одно ведро заполнено, его единицы объединяются и перемещаются в соседний контейнер. То есть самый правый контейнер может содержать только девять единичных единиц. 10-й блок будет связан с первыми девятью, и весь пакет будет перемещен в контейнер слева от него.
Каждый контейнер может содержать только девять пакетов любого размера. Самый правый контейнер может содержать только девять единиц, прежде чем они будут упакованы. Контейнер слева может содержать только 9 связок. 10-ый пучок восстанавливается вместе и перемещается в соседний контейнер. Поскольку контейнеры продолжают заполняться, цикл повторяется; Контейнер слева всегда может содержать девять пакетов того, что может вместить правый контейнер.
Система подсчета base-10, с которой мы больше всего знакомы, называется десятичной, но существуют и другие системы подсчета. Ключ в том, что предел каждого контейнера на один меньше, чем у основания. Например, предел каждого контейнера в восьмеричной системе счисления (base-8) равен 7. В шестнадцатеричном (base-16) каждый контейнер содержит 15 единиц. В шестнадцатеричном формате буквы от A до F часто используются для обозначения величин от 10 до 15.
В двоичном (base-2) каждый контейнер ограничен одной единицей или комплектом.
Поскольку каждый контейнер ограничен одной единицей или пакетом, значение, которое составляет двоичное число, может быть только единицей или нулем. Он либо полный (значение один), либо пустой (значение ноль). Когда строка значений контейнера записана, она может напоминать серию галочек, как будто в списке: 1 может считаться галочкой, а 0 — отсутствием проверки.
Функции преобразования
Преобразование значений из одной базы в другую может быть утомительным, если выполняется вручную в зависимости от размера значения. Чтобы облегчить жизнь, в PHP есть несколько встроенных функций, которые можно использовать для преобразования чисел из одной базы в другую: decbin()
, bindec()
, decoct()
, octdec()
, dechex()
, hexdec()
и base_convert()
.
Функция decbin()
принимает число в десятичном формате и возвращает строку, представляющую двоичный эквивалент. Функция-аналог bindec()
принимает строку, представляющую двоичное число, и возвращает десятичное значение.
Функция decoct()
принимает десятичное число и возвращает строку, представляющую ее восьмеричный эквивалент. Его аналог octdec()
принимает строковое представление восьмеричного значения и возвращает десятичное число.
dechex()
принимает десятичное значение и возвращает строковое представление шестнадцатеричного значения; hexdec()
принимает строку, представляющую шестнадцатеричное число, и возвращает десятичный эквивалент.
<?php $num = 21; echo "Decimal value: $numn"; echo "Binary value: " . decbin($num) . "n"; echo "Octal value: " . decoct($num) . "n"; echo "Hexadecimal value: " . dechex($num) . "n";
В приведенном выше коде десятичное значение 21 хранится в переменной $num
. Функции decbin()
, decoct()
и dechex()
используются для отображения двоичного, восьмеричного и шестнадцатеричного эквивалентов; двоичное значение равно 10101, восьмеричное значение равно 25, а шестнадцатеричное значение равно 15.
Функция base_convert()
используется для преобразования между произвольными базами. Он принимает два аргумента: первый — исходная база, а второй — желаемая база. Давайте предположим, что конкретной программе необходимо преобразовать значения base-7 и base-11; нет удобных функций для выполнения этих задач, поэтому используется base_convert()
.
<?php $num = 21; echo "Decimal value: $numn"; echo "Base-7 value: " . base_convert($num, 10, 7) . "n"; echo "Base-11 value: " . base_convert($num, 10, 11) . "n";
Десятичное число 21 для основания-7 равно 30, а для основания-11 — 1А.
Конечно, base-7 и base-11, конечно, кажутся странными, но они иллюстрируют, как работает base_convert()
. Возможно, более реалистично будет использовать base_convert()
для прямого преобразования двоичных, восьмеричных и шестнадцатеричных значений, когда base_convert()
функция недоступна.
<?php $octNum = 25; echo "Octal value: $octNumn"; echo "Binary value: " . base_convert($octNum, 8, 2) . "n";
Битовые операторы
Вернувшись в раздел теории чисел, вы увидели, что каждый двоичный контейнер может быть либо полным (иметь значение один), либо пустым (значение ноль). Каждый пакет, который заполняет контейнер, мы называем «бит».
Побитовое И
Побитовый оператор -и является амперсандом ( &
). Он принимает два значения и логически возвращает их двоичные значения. Рассмотрим следующий пример:
Побитовая операция — и принимает двоичное представление двух чисел и возвращает построенное число, на основе которого оба поля имеют значение 1,5 и 3 = 1, поскольку оба двоичных представления имеют только значение 1 в самом правом месте.
Побитовое Или
Побитовый оператор или — это труба ( |
). Он принимает два значения и логически изменяет их двоичные значения.
Побитовая операция или принимает двоичное представление двух чисел и возвращает число, построенное на основе того, какие поля хотя бы в одном из них имеют значение 1. 5 | 3 = 7, так как между двумя двоичными представлениями есть значение 1 в каждом местоположении.
Побитовый-Исключительный Или (XOR)
Битовый оператор xor является кареткой ( ^
). В отличие от побитового — или где 1 возвращается для конкретного бита, если установлен хотя бы один из битов, битовый xor будет возвращать только один, если установлен только один из битов.
Побитовый xor вернет единицу, только если установлен один из битов. Если ни один из битов не установлен или оба бита установлены, возвращается ноль. 5 ^ 3 = 6.
Побитовый комплимент
Оператор комплимента — тильда ( ~
). Он переворачивает биты в значении так, чтобы позиции, которые были 1, были бы тогда 0, и позиции, которые были нулем, были бы тогда 1.
Поскольку комплимент переключает значения битов от 1 до 0 и от 0 до 1 в двоичном представлении значения, ~ 5 = 2.
Маскировка с помощью бинарных операторов
Ранее мы также кратко увидели, как двоичные числа могут использоваться в качестве типа контрольного списка; Побитовые операторы PHP могут оказаться полезными в манипулировании и маскировании этих подсчетов, работая с каждым битом.
<?php // people and values from previous chart $people = array( "Joe" => 3, "Ned" => 20, "Sally" => 14 ); // mask values if person has certain animal $mask = array( "rabbit" => bindec("00001"), "dog" => bindec("00010"), "cat" => bindec("00100"), "bird" => bindec("01000"), "snake" => bindec("10000") ); foreach ($people as $person => $value) { // who has a pet dog? if (($value & $mask["dog"]) == $mask["dog"]) { echo "$person has a dog.n"; } // who has a snake if (($value & $mask["snake"]) == $mask["snake"]) { echo "$person has a snake.n"; } // who does NOT have a cat? if ((~$value & $mask["cat"] ) == $mask["cat"]) { echo "$person does not have a cat.n"; } // who has both a cat and a bird? if (($value & $mask["cat"] + $mask["bird"]) == $mask["cat"] + $mask["bird"]) { echo "$person has both a cat and a bird.n"; } }
В этом примере данные из диаграммы опроса домашних животных, которые вы видели ранее, присваиваются массиву с именем $ people. Затем для каждого животного присваивается значение маски в зависимости от его положения на диаграмме обследования. Полученная двоичная строка преобразуется в десятичное число с помощью bindec()
. Значения хранятся в массиве $ mask.
Цикл foreach
циклически проходит по каждому элементу и проверяет различные условия, которые мы установили. Каждое условие использует бинарные операторы для маскировки значений, которые нам не нужны. Если изолированное значение соответствует значению маски, это означает, что результаты опроса соответствуют критериям, которые мы ищем. Важно следить за порядком операций и использовать круглые скобки, чтобы операторы работали с правильными данными.
Резюме
Эта статья определенно охватывает много материала! Я рассказал вам о том, как структурированы счетные системы, показал, как выполнять преобразование между различными системами счисления, а затем как использовать двоичные операторы. Статья завершилась простым примером маскировки битов, чтобы собрать все воедино. Надеюсь, теперь вы сможете с легкостью включить эти, казалось бы, хитрые концепции в свои сценарии!
Изображение через Fotolia