Битовая логика в ISBL. Проверка четности

13 8

Назначение

В данной статье описывается принцип работы логических операторов ISBL: and, or, not, а также рассматривается возможность их использования не только в условиях.
Статья, в первую очередь, направлена на расширение кругозора и позволит лучше понять, как работает интерпретатор ISBL.
Также в статье есть пример нестандартного использования логических операторов - определение четности целого числа.

Принцип работы

Логические операторы and (и), or (или), not (не) в ISBL по сути являются побитовыми. Для наглядности можно провести аналогию с операторами из C-подобных языков: 

ISBL C# / C++ / Java / …  Описание
and &  Побитовое И
or |  Побитовое ИЛИ
not ~  Побитовое отрицание


Логические операторы в ISBL, в первую очередь, работают с логическими значениями TRUE и FALSE, которые являются системными константами, значения которых -1 и 0 соответственно. Т.к. мы знаем, что логические операторы производят побитовые вычисления, разложим эти значения на битовые представления:

Константа Значение Битовое представление
TRUE -1 1111…1111
FALSE 0 0000…0000


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

Примечание: из-за этого, если в условии забыть написать сравнение какого-то целого числа (например, if List.IndexOfName(‘name’)), то ошибки не будет, но условие будет отрабатывать неверно.

Применение

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

  • Использование логических операторов не по прямому назначению снижает понятность кода;
  • Использовать в условиях not над математическими выражениями и числами надо осторожно, т.к. оба выражения "if 3" и "if not 3" дадут истину. Ложь можно получить только как "if not -1";
  • Целые числа в IS-Builder'е представляются 32 разрядами, и лучше воздержаться от логических операций с числами, не попадающими в диапазон 32х разрядных чисел.

Примеры

Проверка четности

Хорошим примером применимости логических операторов является определение четности целого числа. Предполагается, что это проверка будет оформлена в виде функции, которая возвращает логическое значение.
Выражение "and 1" даст нам последний бит числа, результатом будет являться 1 для нечетных и 0 для четных. Далее их нужно привести к стандартным значениям TRUE и FALSE, сделать это можно вычитанием единицы.

Код функции:

Assert(Round(Value; 0) = Value; "Переданное значение не является целым числом")
Result = (Value and 1) - 1

Условие наличия элемента в списке

Простой пример, просто показывающий, что так можно, но такая реализация плохо читается, хотя и может пригодиться в сложных условиях.
Вот 3 идентичных варианта написания условия наличия элемента в списке для использования в if’e:

// Обычный
if List.IndexOfName(ValueName) <> -1
  // Какие-то вычисления
endif

 // -1 инвертируется в 0, остальные значения в ненулевое целое число
if not List.IndexOfName(ValueName)
  // Какие-то вычисления
endif

 // Подобно примеру с четностью
if List.IndexOfName(ValueName) + 1
  // Какие-то вычисления
endif

 

Михаил Извеков

Берут меня сомнения, что

-1 1111…1111
Степан Мурашов

Сомнения зря берут. Называется это дополнительный код, и для представления знаковых чисел используется именно он. Подробнее на wiki

Михаил Извеков

Век живи - век учись.

Арслан Абакаров

Epic!

Как здесь уже говорили: век живи - век учись. :)

Михаил Босомыкин

Ох, какие мы догадки не строили почему True = -1 :) 

Алексей Григорьев

"Ложь можно получить только как "if not 0"

Ложь так не получается, получается вот так: "if not -1"

Григорий Бехтерев
Ох, какие мы догадки не строили почему True = -1 :) 

Какие например? Интересно узнать.

Алексей Филиппов
"Ложь можно получить только как "if not 0" Ложь так не получается, получается вот так: "if not -1"

Алексей, спасибо что заметил, поправил

Авторизуйтесь, чтобы написать комментарий