Множество значений логического типа logical содержит всего два элемента - true (истина) и false (ложь). Эти константы определены так, что true равняется 1, false равняется 0 и true > false.

Значения логического типа обычно получаются в результате сравнения с использованием следующих операторов:

  • ==: равенство. Например, a == b возвращает 1, если a равно b.
  • ~=: неравенство. Например, x ~= y возвращает 1, если x не равно y.
  • <: меньше. Например, p < q возвращает 1, если p меньше q.
  • >: больше. Например, m > n возвращает 1, если m больше n.
  • <=: меньше или равно. Например, r <= s возвращает 1, если r меньше или равно s.
  • >=: больше или равно. Например, t >= u возвращает 1, если t больше или равно u.
class(3 < 4)
ans =
    'logical'

Сравнение значений полезно в исследовании математических выражений, анализе данных (фильтрации по условию) и в построении управляющих конструкций.

Кроме операторов сравнения для построения логических выражений используются логические операторы:

  • ~ - отрицание
  • && - логическое И
  • || - логическое ИЛИ

Например, x > 0 && x < 10 истинно только в том случае, если x больше 0 и одновременно меньше 10. Обычно мы бы сказали, что x находится между 0 и 10, не включая конечные значения.

x = 5;
disp(x > 0 && x < 10);
x = -1;
disp(x > 0 && x < 10);
x = 11;
disp(x > 0 && x < 10);
1
0
0

mod(n, 2) == 0 || mod(n, 3) == 0 истинно, если выполняется хотя бы одно из условий, то есть если число делится на 2 или на 3. В этом случае одна или другая часть (или обе) должны быть истинными, чтобы результат был истинным.

n = 1;
disp(mod(n, 2) == 0 || mod(n, 3) == 0);
n = 2;
disp(mod(n, 2) == 0 || mod(n, 3) == 0);
n = 3;
disp(mod(n, 2) == 0 || mod(n, 3) == 0);
n = 2 * 3;
disp(mod(n, 2) == 0 || mod(n, 3) == 0);
0
1
1
1

Наконец, оператор отрицания ~ инвертирует булево выражение, поэтому ~ x > y будет истинным, если x > y ложно, то есть если x меньше или равно y.

x = -1;
y = 1;
disp(~(x > y));
1

Приведем таблицы результатов этих логических операций для всех возможных значений операндов (в алгебре логики такие такие таблицы называются таблицами истинности).

x ~x
1 0
0 1


x y x && y x || y
0 0 0 0
0 1 0 1
1 0 0 1
1 1 1 1


Замечание. Часто допускают ошибки при написании булевых выражений. Например, запись number == 5 || 6 || 7 в MATLAB некорректна, так как оператор || должен соединять булевы выражения. Правильный вариант: (number == 5) || (number == 6) || (number == 7). Хотя это кажется громоздким, это необходимо; нельзя использовать сокращения. Аналогично, выражение a < b < c интерпретируется как (a < b) < c. Чтобы проверить a < b < c математически, следует писать (a < b) && (b < c).

В логических выражениях могут встречаться как арифметические операции, так и логические. Порядок выполнения операций определяется их приоритетом (в других языках программирования приоритеты операций могут быть другими):

  1. Скобки ()
  2. Отрицание ~
  3. Умножение * и деление /
  4. Сложение + и вычитание -
  5. Операторы сравнения: меньше <, нестрогое меньше <=, больше >, нестрогое больше >=, равенство ==, не равно ~=
  6. Логические И &&
  7. Логическое ИЛИ ||

Операции с одинаковым приоритетом выполняются по порядку слева направо. Для изменения порядка необходимо воспользоваться кргулыми скобками ().

При вычислении булевских выражений их значение может стать известным еще до конца вычисления всего выражения. Например:

h_plus = 10e-8; % молярная концентрация H+
% Вычисление кислотности раствора PH
is_water = (h_plus > 0) && (6.5 <= -log10(h_plus) && -log10(h_plus) <= 8.5)

В случае, если бы h_plus = 0, уже после первого операнда операции && ясно, что результат всего выражения - ложь 0 (false), поэтому второй операнд вычисляться не будет. Если бы первый операнд отсутсвовал, то формула была бы ошибочна при неккоректном входном аргументе h_plus.

Нередко при составлении программ со сложными логическими выражениями, необходимо строить их отрицания (см. “На тему вложенности кода”). Для этого полезно воспользоваться следующими тождествами:

  • ~~a \(\equiv\) a
  • ~(a && b) \(\equiv\) (~a) || (~b)
  • ~(a || b) \(\equiv\) (~a) && (~b)

Последние два тождества известны как законы де Моргана.

Следует иметь ввиду отрицания операторов отношения:

Оператор Определение Логические противоположности
== Равно ~=
~= Не равно ==
< Меньше >=
<= Меньше или равно >
> Больше <=
>= Больше или равно <

Понимание логических противоположностей позволяет нам иногда избавляться от операторов отрицания ~. Они часто усложняют чтение кода, и без них наши намерения становятся яснее.

Например, если бы мы написали следующий код на MATLAB:

if ~(age >= 17)
    disp("Вы слишком молоды, чтобы получить водительские права!")
end

Следовало бы упростить и написать вместо этого:

if age < 17
    disp("Вы слишком молоды, чтобы получить водительские права!")
end

Законы де Моргана также могут облегчить понимание условий. Рассмотрим пример:

if ~((phone_charge >= 0.50) && (phone_storage >= 0.15))
    disp("Вы не можете обновить телефон. Низкий заряд батареи или недостаточно свободного места.")
else
    disp("Идет обновление... Может потребоваться несколько перезагрузок.")
end

После преобразования:

if (phone_charge < 0.50) || (phone_storage < 0.15)
    disp("Вы не можете обновить телефон. Низкий заряд батареи или недостаточно свободного места.")
else
    disp("Идет обновление... Может потребоваться несколько перезагрузок.")
end

Вместо применения законов Де Моргана, можно было избавиться от оператора отрицания ~, поменяв местами логические части «тогда» и «иначе» в условии:

if (phone_charge >= 0.50) && (phone_storage >= 0.15)
    disp("Идет обновление... Может потребоваться несколько перезагрузок.")
else
    disp("Вы не можете обновить телефон. Низкий заряд батареи или недостаточно свободного места.")
end

Последняя версия, вероятно, лучшая из трех, потому что она очень точно соответствует первоначальному логическому утверждению.

В программировании почти всегда существует несколько способов решить любую задачу. Хорошие программы спроектированы, делая выбор в пользу ясности, простоты и изящности.