Битовые операции

Эта тема показывает, как использовать битовые операции в MATLAB®, чтобы управлять битами чисел. Работа на битах непосредственно поддерживается большинством современных центральных процессоров. Во многих случаях управление битами номера таким образом быстрее, чем выполнение арифметических операций как деление или умножение.

Представления номера

Любой номер может быть представлен битами (также известный как двоичные цифры). Битовое или число в двоичной форме содержит 1 с и 0s, чтобы указать, какие степени 2 присутствуют в номере. Например, 8-битная двоичная форма 7

00000111

Набор 8 битов также называется 1 байтом. В бинарных представлениях биты считаются справа налево, таким образом, первый бит в этом представлении является 1. Этот номер представляет 7 потому что

22+21+20=7.

При вводе числа в MATLAB, он принимает, что числа являются двойной точностью (64-битное бинарное представление). Однако можно также задать числа с одинарной точностью (32-битное бинарное представление) и целые числа (подписанный или без знака от 8 до 64 битов). Например, большая часть памяти эффективный способ сохранить номер 7 с 8-битным беззнаковым целым:

a = uint8(7)
a = uint8
    7

Можно даже задать двоичную форму непосредственно с помощью префиксного 0b сопровождаемый двоичными цифрами (для получения дополнительной информации, смотрите Шестнадцатеричные и Двоичные значения). MATLAB хранит номер в целочисленном формате с наименьшим количеством количества битов. Вместо того, чтобы задать все биты, необходимо задать только крайний левый 1 и все цифры справа от него. Биты слева от того бита являются тривиально нулевыми. Таким образом, номер 7:

b = 0b111
b = uint8
    7

MATLAB хранит отрицательные целые числа с помощью дополнения two. Например, рассмотрите 8-битное целое число со знаком-8. Найти дополнительную комбинацию двоичных разрядов two для этого номера:

  1. Начните с комбинации двоичных разрядов положительной версии номера, 8: 00001000.

  2. Затем инвертируйте все биты: 11110111.

  3. Наконец, добавьте 1 к результату: 11111000.

Результат, 11111000, комбинация двоичных разрядов для-8:

n = 0b11111000s8
n = int8
    -8

MATLAB исходно не отображает двоичный формат чисел. Для этого можно использовать dec2bin функция, которая возвращает вектор символов двоичных цифр для положительных целых чисел. Снова, эта функция возвращает только цифры, которые не являются тривиально нулевыми.

dec2bin(b)
ans = 
'111'

Можно использовать bin2dec переключаться между этими двумя форматами. Например, можно преобразовать двоичные цифры 10110101 к десятичному формату с командами

data = [1 0 1 1 0 1 0 1];
dec = bin2dec(num2str(data))
dec = 181

cast и typecast функции также полезны, чтобы переключиться среди различных типов данных. Эти функции подобны, но они отличаются по тому, как они обрабатывают базовую систему хранения номера:

  • cast — Изменяет базовый тип данных переменной.

  • typecast — Преобразует типы данных, не изменяя базовые биты.

Поскольку MATLAB не отображает цифры двоичного числа непосредственно, необходимо обратить внимание на типы данных, когда вы работаете с битовыми операциями. Некоторые функции возвращают двоичные цифры как вектор символов (dec2bin), некоторые возвращают десятичное число (bitand), и другие возвращают вектор самих битов (bitget).

Побитовое маскирование с логическими операторами

MATLAB имеет несколько функций, которые позволяют вам выполнить логические операции на битах двух двоичных представлений равной длины чисел, известных как побитовое маскирование:

  • bitand — Если обе цифры равняются 1, то получившаяся цифра является также 1. В противном случае получившаяся цифра 0.

  • bitor — Если любая цифра равняется 1, то получившаяся цифра является также 1. В противном случае получившаяся цифра 0.

  • bitxor — Если цифры отличаются, то получившаяся цифра является 1. В противном случае получившаяся цифра 0.

В дополнение к этим функциям поразрядное дополнение доступно с bitcmp, но это - унарная операция, которая инвертирует биты только в одном номере за один раз.

Одно использование побитового маскирования должно запросить состояние конкретного бита. Например, если вы используете операцию побитового И с двоичным числом 00001000, можно запросить состояние четвертого бита. Можно затем переключить тот бит к первой позиции так, чтобы MATLAB возвратил 0, или 1 (следующий раздел описывает бит, переключающий более подробно).

n = 0b10111001;
n4 = bitand(n,0b1000);
n4 = bitshift(n4,-3)
n4 = uint8
    1

Битовые операции могут иметь удивительные приложения. Например, рассмотрите 8-битное бинарное представление номера n=8:

00001000

8 степень 2, таким образом, ее бинарное представление содержит один 1. Теперь рассмотрите номер (n-1)=7:

00000111

Путем вычитания 1, инвертируются все биты, запускающиеся в самом правом 1. В результате, когда n степень 2, соответствующие цифры n и (n-1) всегда отличаются, и побитовое И возвращает нуль.

n = 0b1000;
bitand(n,n-1)
ans = uint8
    0

Однако, когда n не степень 2, затем самый правый 1 для 20 бит, таким образом, n и (n-1) имейте весь одинаковый биты за исключением 20 бит. Для этого случая побитовое И возвращает ненулевой номер.

n = 0b101;
bitand(n,n-1)
ans = uint8
    4

Эта операция предлагает простую функцию, которая работает с битами данного входного номера, чтобы проверять, является ли номер степенью 2:

function tf = isPowerOfTwo(n)
  tf = n && ~bitand(n,n-1);
end

Использование операции И короткой схемы && проверки, чтобы убедиться тот n не нуль. Если это, то функция не должна вычислять bitand(n,n-1) знать, что правильным ответом является false.

Сдвиг битов

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

  • bitshift(A,N) переключает биты A налево N цифры. Это эквивалентно умножению A 2N.

  • bitshift(A,-N) переключает биты A направо N цифры. Это эквивалентно делению A 2N.

Этими операциями иногда является записанный A<<N (сдвиг влево) и A>>N (сдвиг вправо), но MATLAB не использует << и >> операторы с этой целью.

Когда биты номера смещены, некоторые биты падают с конца номера и 0s или 1s введены, чтобы заполнить недавно созданное пространство. Когда вы переключаете биты налево, биты заполнены в справа; когда вы переключаете биты направо, биты заполнены в слева.

Например, если вы переключаете биты номера 8 (двоичный файл: 1000) направо одной цифрой, вы добираетесь 4 (двоичный файл: 100).

n = 0b1000;
bitshift(n,-1)
ans = uint8
    4

Точно так же, если вы переключаете номер 15 (двоичный файл: 1111) налево двумя цифрами, вы добираетесь 60 (двоичный файл: 111100).

n = 0b1111;
bitshift(15,2)
ans = 60

Когда вы переключаете биты отрицательного числа, bitshift сохраняет бит со знаком. Например, если вы переключаете целое число со знаком-3 (двоичный файл: 11111101) направо 2 цифрами, вы добираетесь-1 (двоичный файл: 11111111). В этих случаях, bitshift заполняет слева с 1s, а не 0s.

n = 0b11111101s8;
bitshift(n,-2)
ans = int8
    -1

Запись битов

Можно использовать bitset функционируйте, чтобы изменить биты в номере. Например, измените первый бит номера 8 к 1 (который добавляет 1 к номеру):

bitset(8,1)
ans = 9

По умолчанию, bitset биты щелчков к на или 1. Можно опционально использовать третий входной параметр, чтобы задать битовое значение.

bitset не изменяется на несколько битов целиком, таким образом, необходимо использовать for цикл, чтобы измениться на несколько битов. Поэтому биты, которые вы изменяете, могут быть или последовательными или непоследовательными. Например, измените на первые два бита двоичного числа 1000:

bits = [1 2];
c = 0b1000;
for k = 1:numel(bits)
    c = bitset(c,bits(k));
end
dec2bin(c)
ans = 
'1011'

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

data = [1 1 0 0 1 1 0 1];
n = length(data);
dec = 0b0u8;
for k = 1:n
    dec = bitset(dec,n+1-k,data(k));
end
dec
dec = uint8
    205
dec2bin(dec)
ans = 
'11001101'

Чтение последовательных битов

Другое использование битной перемены должно изолировать последовательные разделы битов. Например, считайте последние четыре бита в 16-битном номере 0110000010100000. Вспомните, что последние четыре бита слева от бинарного представления.

n = 0b0110000010100000;
dec2bin(bitshift(n,-12))
ans = 
'110'

Чтобы изолировать последовательные биты посреди номера, можно объединить использование перемены бита с логическим маскированием. Например, чтобы извлечь 13-е и 14-е биты, можно переключить биты направо 12 и затем замаскировать получившиеся четыре бита с 0011. Поскольку входные параметры к bitand должен быть тот же целочисленный тип данных, можно задать 0011 как 16-битное целое число без знака с 0b11u16. Без -u16 суффикс, MATLAB хранит номер как 8-битное целое число без знака.

m = 0b11u16;
dec2bin(bitand(bitshift(n,-12),m))
ans = 
'10'

Другой способ считать последовательные биты с bitget, который читает заданные биты из номера. Можно использовать обозначение двоеточия, чтобы задать несколько последовательных битов, чтобы читать. Например, считайте последние 8 битов n.

bitget(n,16:-1:8)
ans = 1x9 uint16 row vector

   0   1   1   0   0   0   0   0   1

Чтение непоследовательных битов

Можно также использовать bitget считать биты из номера, когда биты не друг рядом с другом. Например, считайте 5-е, 8-е, и 14-е биты из n.

bits = [14 8 5];
bitget(n,bits)
ans = 1x3 uint16 row vector

   1   1   0

Смотрите также

| | | | | |

Похожие темы