Поразрядные операторы

Поразрядные операторы позволяют работать с целыми десятичными числами, как с двоичными. Зачем это нужно? Двоичные числа — это та форма представления информации, с которой имеет дело компьютер на уровне аппаратной реализации. Поэтому использование поразрядных операторов позволяет осуществлять многие операции гораздо быстрее, чем с применением, например, обычных арифметических операторов. Кроме того, сохранение в одном числе нескольких побитовых флагов дает экономию оперативной памяти. Поразрядное программирование было чрезвычайно важно на ранних этапах развития компьютерной техники, когда любая оптимизация имела огромную важность в виду предельной ограниченности ресурсов вычислительной машины. В настоящее время оно существенно сдало свои позиции, и если имеет серьезное значение, то только в системной области. В ActionScript поразрядные операторы — это скорее рудиментарное наследие языка С, нежели требуемые на практике компоненты. Действительно, большая часть смысла их существования теряется в связи с тем, что они в ActionScript напрямую не связаны с соответствующими аппаратными командами. Однако иметь о них представление нужно хотя бы для общей эрудиции.

С одним примером поразрядного программирования мы уже встречались.


Вспомните функцию ASSetPropFlags(), устанавливающую значения для атрибутов свойств. Настройки для трех атрибутов она принимает в виде одного числа. Каждый бит этого числа в двоичном представлении хранит установку для одного атрибута. Например, число 7 (двоичное 111), переданное второму параметру, означает, что свойство будет защищено от удаления, переопределения и просмотра циклом for—in. Число 5 (двоичное 101) разрешает удаление, но запрещает перечисление и переопределение — и т. д. Если бы для каждого атрибута функция ASSetPropFlags() принимала отдельный параметр, то число ее аргументов достигло бы 8. А если бы атрибутов было не 3, а 5? Более 20 параметров —это слишком много даже для служебной функции. Использование битов числа в качестве информационных флагов позволяет чрезвычайно компактно записывать значительное количество информации. Пожалуй, только эта возможность поразрядного программирования имеет в ActionScript определенное практическое значение.

Логические поразрядные операторы
Булевым величинам true и false можно поставить в соответствие биты 1 и 0. Тогда любое число можно считать последовательностью логических величин. Логическая операция над такими числами будет означать, что операция И, ИЛИ, исключающее ИЛИ будет проведена над каждой парой разрядов.


Например:

00011101
00111000
------------ ИЛИ
00111101

Чтобы проделать ту же операцию средствами ActionScript, набираем:

trace(parseInt("00011101", 2) | parseInt("00111000", 2)); // Выводит: 61

Так как напрямую ActionScript работать с двоичными числами не умеет, нам пришлось преобразовать хранящие их строки в целые числа при помощи функции parseInt. Чтобы получить результат в двоичной форме, можно воспользоваться методом toString():

trace((parceInt("00011101",2) | parceInt("0011100",2)).toString(2));
// Выводит: 111101

Всего в ActionScript имеются 4 поразрядных логических оператора:

& Поразрядное И
| Поразрядное ИЛИ
^ Поразрядное исключающее ИЛИ (XOR). Устанавливает бит 1, если один из битов операндов равен 1. Если оба бита равны 0 или 1б устанавливает 0
~ Поразрядное НЕ

Для тренировки попробуйте самостоятельно провести над приведенными выше двоичными числами операцию XOR.

В том, как удобно сохранять в одном числе несколько побитовых флагов, мы уже убедились. Возникает вопрос; а как прочитать при необходимости значение того или иного флага? Сделать это можно, проведя операцию логического И над анализируемым значением и двоичным числом, в котором бит 1 установлен только в интересующем разряде.


Если возвращенный результат будет отличен от нуля, значит, флаг был установлен. Если возвращается нуль, то и соответствующий разряд хранил 0:

// Проверяем, чему равен четвертый бит
1001101
0001000
------------ И
0001000 ==> флаг установлен
// В виде ActionScript:
if (parseInt("1001101", 2) & parseInt("1000",2)!= 0) {
trace(true);
} else {
trace (false);
} // Выводит: true

Аналогично арифметическим операторам, существуют поразрядные операторы, совмещающие проведение логической операции с присваиванием результата левому операнду. От простых поразрядных логических операторов они отличаются наличием знака «равно»: «&=», «|=», «^=», «~=».

В качестве примера использования логических поразрядныx присваиванием приведем операцию исключающего ИЛИ:

var bit:Number = parseInt("1001001", 2);
bit ^= parseInt("1111000",2);
trace(bit.toString(2)); // Выводит: 110001

Число, передаваемое побитовому оператору, преобразуется из 64-битного с плавающей точкой в 32-битное целое. Это означает, что работать с дробными числами и числами, превышающими по модулю 232, побитовые операторы не могут.

Операторы поразрядного сдвига
Операторы двоичного сдвига позволяют проводить быстрое умножение или деление на степень 2.

Кроме того, они полезны, если необходимо прочитать значение какого-то конкретного бита. Сдвиг вправо осуществляется оператором «>>». Его синтаксис:

numberInt >> n.

где:
• numberint — целое число, разряды которые должны быть сдвинуты;

• n — количество позиций, на которые следует сместить разряды.

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

000111001
----------------- Сдвиг вправо на три разряда
000000111
// В виде ActionScript:
trace((parseInt("111001", 2) >> 3).toString(2)); // Выводит: 111

Результат сдвига разрядов числа вправо на n позиций аналогичен его делению на 2n (остаток отбрасывается):

trace(111 >> 3); // Выводит: 13
trace((111-111 %(2*2*2))/(2*2*2)); // Выводит: 13

Практически аналогичен оператору «>>» оператор беззнакового поразрядного сдвига вправо «>>>». Единственное их отличие состоит в том, что «>>>» заполняет освобождающиеся разряды всегда нулями, вне зависимости от знака операнда:

trace(-33>>2); // Выводит: -9
trace((-33)>>>2); // Выводит: 1073741815

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

При желании можно осуществить сдвиг разрядов числа влево. Для этого в ActionScript существует оператор «<<». Результат сдвига на n позиций влево будет аналогичен умножению числа на 2n:

trace(10<<3); // Выводит: 80
trace(10*2*2*2); // Выводит: 80

Помимо обычных операторов двоичного сдвига, в ActionScript существуют операторы, совмещающие смещение разрядов числа с присвоением результата хранящей его переменной. Это операторы «>>=», «>>>=», «<<=». Пример:

var per:Number=16;
per>>=4;
trace(per); // Выводит: 1

На практике побитовые операторы сдвига достаточно часто применяются лишь с одной целью — они позволяют минимумом кода упаковать RGB-составляющие цвета в одно число. Для примера приведем скрипт, задающий формулу белого цвета:

var R:Number = 255, G:Number = 255, B:Number = 255;
var color = R << 16 | G << 8 | B;
trace(color == 0xFFFFFF); // Выводит: true

Оцените статью: (0 голосов)
0 5 0

Статьи из раздела Action Script на эту тему:
Арифметические операторы
Виды операторов
Логические операторы
Операторы равенства и сравнения
Служебные операторы

Вернуться в раздел: Action Script / 5. Операторы