Побитовые операции над логическими значениями

Насколько мне известно, побитовые операторы выполняют проверку всех соответствующих битов, как в:

echo 64 | 32;   //prints 96
echo 'a' & 'b'; //prints `

Пока условно && а также || операторы выполняют операции над логическими значениями:

echo (int)(true && false); //prints: 0
echo (int)(true || false); //prints: 1

Когда я (в своей голове) хочу предсказать результат побитовой операции, я сначала преобразовываю значения в их двоичное представление (которое зависит от типа данных). После этого я сравниваю его побитно и преобразовываю результат в подходящий тип вывода (который, я полагаю, определяется операндами). Хотя в какой-то момент я попытался сделать то же самое с логическими значениями, которые (насколько мне известно) состоят только из одного бита в памяти, делая true соответствует 1₂и делая false соответствует 0₂ (в двоичном виде). Поэтому выполнение побитовых операций над этими значениями должно привести к тому же результату, что и для && а также ||, право? Чтобы показать вам, что я имею в виду:

true & false    =>      1₂ & 0₂      =>      0₂     =>     false
true | false    =>      1₂ | 0₂      =>      1₂     =>     true
~true           =>      ~1₂          =>      0₂     =>     false

(Не включая xor, так как нет соответствующего условного логического оператора.)

Мне кажется, что поведение должно быть действительно эквивалентно условным операторам:

true && false   =>      false
true || false   =>      true
!true           =>      false

Итак, поэтому я установил этот код, чтобы проверить его:

    echo "true AND false: " . ((true && false) ? "1" : "0") . "<br />\n";
echo "true OR false: " . ((true || false) ? "1" : "0") . "<br />\n";
echo "NOT true: " . ((!true) ? "1" : "0") . "<br />\n";

echo "<br />\n";

echo "true BITAND false: " . ((true & false) ? "1" : "0") . "<br />\n";
echo "true BITOR false: " . ((true | false) ? "1" : "0") . "<br />\n";
echo "BITNOT true: " . ((~true) ? "1" : "0") . "<br />\n";

Это дало мне следующий вывод:

верно и ложно: 0
верно или ложно: 1
НЕ верно: 0

истина БИТАН ложь: 0
истина битор ложь: 1

Неустранимая ошибка: неподдерживаемые типы операндов в C: \ Abyss Web Server \ htdocs \ handler.php в строке 21

Итак, из этого у меня есть два вопроса:

  1. Какой смысл с && а также ||, если мы (как кажется) можем использовать & а также | вместо логических значений?
  2. Почему я не могу сделать ~true (или другими словами, почему не поддерживаются логические значения)? Для меня это звучит логично, что ~true возвращается false,

Я придумал одну вещь, будучи && а также || будет (иногда) бросать значения в bool и затем вернуть правильные результаты, если мы (по ошибке) получим значение, которое не имеет типа bool, Но чтобы решить эту проблему, разве мы не можем сначала сделать бросок? Такие как:

if ((bool)$foo & (bool)$bar) { ...

Такое ощущение, что я скучаю по главной части, которая меняет все … Но на случай, если я этого не сделал, я включил столько информации, сколько смог. Может ли кто-нибудь заставить меня понять это немного лучше, ответив на два моих вопроса? Я довольно смущен в этом пункте, и я думал об этом в течение достаточно долгого времени.

2

Решение

Ответ 1

Части логических выражений (||, &&, !, …) оцениваются только при необходимости (слева направо):

  if ($a | func()) { } // func is always called
if ($a || func()) { } // func is not called if $a is true,
// because expression is true whatever func will return
if ($a && func()) { } // func is not called if $a is false,
// because expression is false whatever func will return
func() || exit(); // exit() will be called if func() returns false

Посмотрите на документацию: http://php.net/manual/en/language.operators.logical.php

Ответ 2

~true кажется не имеет смысла true является 0x00...01 а также ~true будет 0xff...fe и не false 0x000...0:

var_dump(~((int)true)); // prints: int(-2)
echo dechex(~((int)true)); // prints: fffffffffffffffe

использование !-оператор вместо:

var_dump(!true); // prints: bool(false)

Продолжить

Используйте побитовые операторы, только если вам нужно изменить биты.

3

Другие решения

true а также false логические флаги, хотя и хранящиеся в памяти как 32-битные или 64-битные значения, должны рассматриваться как булевы значения с двумя состояниями. В конечном итоге вы будете использовать его только для охранников, так что вам не следует делать арифметику над ними. && а также || оценивает как логические флаги, побитовые операторы & и | оценивается как один и тот же из операндов (например, int & int оценивает как int, int && int оценивает как логическое значение).

история такая:
использование && а также || когда вы должны принять решение по некоторым условиям. использование & а также | выполнять булеву арифметику над значениями.

это C ++

C не имеет встроенных логических значений, поэтому любое ненулевое значение trueи ноль false,

0