Шаг 76.
Побитовые операции. Числовые операнды

    На этом шаге мы рассмотрим побитовые операции для числовых операндов.

    Данные в компьютере представляются в виде последовательности битов. В языке Perl определены бинарные операции побитового логического сравнения целых чисел и строк: & (И), | (ИЛИ) и ^ (исключающее ИЛИ), а также унарная операция логического отрицания ~. Результат их вычисления зависит от того, к данным какого типа они применяются: числовым или строковым. Эти операторы различают числовые данные и строки, содержимое которых может быть преобразовано в число.

    Кроме логических операций побитового сравнения, две операции сдвигают влево (<<) и вправо (>>) биты в представлении целых чисел. Эти операторы не работают со строками.

Числовые операнды

    Если хотя бы один операнд в бинарных побитовых операциях является числом, то содержимое второго операнда также должно быть числом. Операнд, являющийся строкой символов, преобразуется в числовое значение. В случае несоответствия содержимого строки десятичному числу ее значение принимается равным 0 и отображается предупреждающее сообщение, если установлен соответствующий режим работы интерпретатора. Все числовые операнды преобразуются к целым числам простым отбрасыванием дробной части, никакого округления не происходит.

    Чтобы понять сущность побитовых операций над числовыми данными, необходимо представлять, как хранятся в программе целые числа. При задании чисел мы можем использовать одно из трех представлений: десятичное, восьмеричное или шестнадцатеричное. Однако в компьютере числа не хранятся ни в одном из указанных представлений. Они переводятся в двоичные числа - числа с основанием 2, цифры которых и называются битами. Двоичные числа представляют собой запись чисел в позиционной системе счисления, в которой в качестве основания используется число 2. Таким образом, двоичные цифры, или биты, могут принимать значения только 0 или 1. Например, десятичное число 10, переведенное в двоичное, представляется в виде 1010. Для обратного перевода этого числа в десятичную форму представления следует, в соответствии с правилами позиционной системы счисления, произвести следующие действия:

    1* (2**3) + 0*(2**2) + 1*(2**1) + 0*(2**0)

    Язык Perl гарантирует, что все целые числа имеют длину 32 бита, хотя на некоторых машинах они могут представляться и 64 битами. Именно с двоичными представлениями целых чисел и работают все побитовые операции, преобразуя и отрицательные, и положительные числа к целому типу данных.

    Операция & побитового логического И сравнивает каждый бит правого операнда с соответствующим битом левого операнда. Если оба сравниваемых бита имеют значение 1, то соответствующий бит результирующего значения операции устанавливается равным 1, в противном случае значением бита результата будет 0. В качестве примера рассмотрим следующее выражение

  45.93  &  100

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

    00000000000000000000000000101101

    Двоичное представление левого операнда 100 будет иметь вид

    00000000000000000000000001100100

    Результатом побитового логического И будет следующая последовательность битов

    00000000000000000000000000100100

    Она соответствует десятичному целому числу 36. Следовательно, значением выражения 45.93 & 100 будет целое число 36.


    Замечание. В этом примере мы специально использовали 32-битное представление целых чисел, хотя для бинарных побитовых операций лидирующие нули не имеют значения. Они существенны только при операциях побитового логического отрицания и сдвигов.

    При побитовой операции логического ИЛИ | бит результата устанавливается равным 1, если хотя бы один из сравниваемых битов равен 1. Операция побитового логического ИЛИ для тех же двух чисел

    45.93 | 100
даст результат равный 109, так как при применении побитового логического ИЛИ к операндам
    00000000000000000000000000101101    (десятичное 45)
и
    00000000000000000000000001100100    (десятичное 100)
дает следующую цепочку битов
    00000000000000000000000001101101    (десятичное 109: 2**6+2**5+2**3+2**2+2**1)

    Побитовое исключающее ИЛИ ^ при сравнении битов дает значение 1 тогда, когда точно один из операндов имеет значение равное 1. Следовательно, 1^1=0 и 0^0=0, в остальных случаях результат сравнения битов равен 1. Поэтому для тех же чисел результатом операции 45. 93 ^ 100 будет десятичное число 73.

    Операция логического отрицания ~ является унарной и ее действие заключается в том, что при последовательном просмотре битов числа все значения 0 заменяются на 1, и наоборот. Результат этой операции существенно зависит от используемого количества битов для представления целых чисел. Например, на 32-разрядной машине результатом операции будет последовательность битов

    11111111111111111111111111111110    ,
представляющая десятичное число 4294967294=231+230+...+21, тогда как на 16-разрядной машине эта же операция даст число 6534=231+230+...+21.

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

  # Битовое представление числа 22: (00000000000000000000000000010110)
  22 >> 2 # Результат: (00000000000000000000000000000101) = 5
  22 << 2 # Результат: (00000000000000000000000001011000) = 88

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

  00000000000000000000000000000001 # положительное число 1
  11111111111111111111111111111110 # обратный код числа 1
                                 1 # добавляем к младшему разряду 1
  11111111111111111111111111111111 # и получаем представление числа -1

    Именно с этим кодом числа -1 будут работать все побитовые операции, если оно будет задано в качестве операнда одной из них.


    Замечание. В языке Perl в арифметических операциях используется представление всех чисел в виде чисел с плавающей точкой удвоенной точности. Целое число можно задавать с 15 значащими цифрами, т.е. максимальное положительное целое число может быть 999 999 999 999 999. Но это число не имеет ничего общего с представлением целых чисел в компьютере, для которых может отводиться 64, 32 или 16 битов, в зависимости от архитектуры компьютера. Во всех побитовых операциях можно предсказать результат только если операндами являются целые числа из диапазона -232-1 ... 232-1, так как ясен алгоритм их представления. Вещественные числа, не попадающие в этот диапазон, преобразуются к целым, но алгоритм их преобразования не описан авторами языка.

    На следующем шаге мы рассмотрим побитовые операции для строковых операндов.




Предыдущий шаг Содержание Следующий шаг