本主题展示了如何在MATLAB®中使用逐位运算来操作数字的位。大多数现代cpu都直接支持对位的操作。万博1manbetx在许多情况下,以这种方式操作数字的位比执行除法或乘法等算术运算要快。
任何数字都可以用位表示(也称为二进制数字).一个数的二进制形式,或以2为基数的形式,包含1和0,以表示该数中存在2的哪个乘方。例如,8位二进制形式的7是
00000111
8位的集合也称为1字节.在二进制表示法中,比特是从右到左计数的,所以在这种表示法中第一个比特是1。这个数字代表7,因为
当您在MATLAB中输入数字时,它假定数字是双精度的(64位二进制表示)。但是,您也可以指定单精度数字(32位二进制表示)和整数(有符号或无符号,从8位到64位)。例如,存储数字7的内存效率最高的方法是使用8位无符号整数:
一个= uint8 (7)
一个=uint87
您甚至可以直接使用前缀指定二进制形式0 b
后面跟着二进制数字(有关更多信息,请参见十六进制和二进制值).MATLAB将数字存储为具有最小位数的整数格式。不需要指定所有的位,只需要指定最左边的1和它右边的所有数字。这个位左边的位都是零。所以数字7是:
b = 0 b111
b =uint87
MATLAB存储负整数使用2的补码。例如,考虑8位有符号整数-8。要找到这个数字的2的补码位模式:
从数字的正数版本8的位模式开始:00001000
.
接下来,翻转所有位:11110111
.
最后,在结果中添加1:11111000
.
结果,11111000
,是-8的位模式:
n = 0 b11111000s8
n =int8-8
MATLAB本身并不显示二进制格式的数字。为此,你可以使用dec2bin
函数,该函数返回正整数的二进制数字字符向量。同样,这个函数只返回非平凡零的数字。
dec2bin (b)
ans = ' 111 '
您可以使用bin2dec
在两种格式之间切换。例如,您可以转换二进制数字10110101
用命令进行十进制格式
数据= [1 0 1 1 0 1 0 1];12月= bin2dec (num2str(数据)
181年12月=
的投
和定型
在不同的数据类型之间切换时,函数也很有用。这些函数是相似的,但它们在处理数字的底层存储方面是不同的:
因为MATLAB不直接显示二进制数的数字,所以在处理逐位运算时必须注意数据类型。有些函数返回二进制数字作为字符向量(dec2bin
),有些返回十进制数(bitand
),其他则返回位本身的向量(bitget
).
MATLAB有几个函数,使您能够对数字的两个等长二进制表示的位执行逻辑操作,称为位屏蔽:
除了这些函数外,按位补码也可用bitcmp
,但这是一个一元操作,每次只换一个数的位。
位屏蔽的一个用途是查询特定位的状态。例如,如果您对二进制数使用逐位的AND操作00001000
,可查询第4位的状态。然后,您可以将该位移到第一个位置,以便MATLAB返回0或1(下一节将更详细地描述位移)。
n = 0 b10111001;陶瓷= bitand (n, 0 b1000);陶瓷= bitshift(陶瓷,3)
陶瓷=uint81
按位操作可以有令人惊讶的应用。例如,考虑数字的8位二进制表示 :
00001000
8是2的幂,所以它的二进制表示只包含一个1。现在考虑一下这个数字 :
00000111
通过减去1,从最右边的1开始的所有位都翻转了。因此,当 是2的幂,对应的数字是 和 总是不同的,按位排列的and返回0。
n = 0 b1000;bitand (n, n - 1)
ans =uint80
然而,当 不是2的幂,那么最右边的1是 一点,所以 和 所有的比特都一样,除了 一些。对于这种情况,按位计算的AND返回一个非零数。
n = 0 b101;bitand (n, n - 1)
ans =uint84
这个运算建议使用一个简单的函数,对给定输入数的位进行运算,以检查该数是否为2的幂:
函数isPowerOfTwo(n) = n && ~bitand(n,n-1);结束
使用短路与操作符&&
检查以确保n
不为零。如果是,则函数不需要计算bitand (n, n - 1)
知道正确答案是假
.
因为按位逻辑运算比较两个数字中相应的位,所以能够移动位来改变比较的位是很有用的。您可以使用bitshift
执行该操作。
bitshift (N)
移动一个
到左通过N
位数。这个等价于乘一个
通过
.
bitshift (A - n)
移动一个
到正确的通过N
位数。这个等价于分一个
通过
.
这些操作有时是写出来的< < N
(左移)和一个> > N
(右移),但MATLAB不使用<<
和>>
操作符。
当一个数字的位移位时,一些位会从这个数字的末尾脱落,然后0
年代或1
S被引入来填充新创建的空间。当你向左移动位时,右边的位就会被填满;当你向右移动位时,左边的位就被填满了。
例如,如果你移动数字8的位(二进制:1000
),你得到4(二进制:One hundred.
).
n = 0 b1000;bitshift (n, 1)
ans =uint84
类似地,如果你移动数字15(二进制:1111
),你得到60(二进制:111100
).
n = 0 b1111;bitshift(15日2)
ans = 60
当你移动一个负数的位时,bitshift
保留带符号的位。例如,如果你移动带符号的整数-3(二进制:11111101
)向右2位,得到-1(二进制:11111111
).在这些情况下,bitshift
左边用1
年代,而不是0
年代。
n = 0 b11111101s8;bitshift (n, 2)
ans =int8-1
你可以使用bitset
函数的作用是:改变一个数中的位。例如,将数字8的第1位改为1(该数字加1):
bitset (8, 1)
ans = 9
默认情况下,bitset
翻转位,在或1。您可以选择使用第三个输入参数来指定位值。
bitset
不会一次改变多个位,所以需要使用a为
循环改变多个位。因此,你改变的位可以是连续的也可以是非连续的。例如,改变二进制数的前两位1000
:
Bits = [1 2];c = 0 b1000;为c = bitset(c,bits(K));结束dec2bin (c)
ans = ' 1011 '
的另一个常见用法bitset
是将二进制的向量转换为十进制格式。例如,使用循环来设置整数的单个位11001101
.
数据= [1 1 0 0 1 1 0 1];n =长度(数据);12月= 0 b0u8;为K = 1:n dec = bitset(dec,n+1- K,data(K));结束12月
12月=uint8205
dec2bin(12月)
ans = ' 11001101 '
位移的另一个用途是隔离连续的位段。例如,读取16位数字的后四位0110000010100000
.回想一下,最后四位在左二进制表示。
n = 0 b0110000010100000;dec2bin (bitshift (n, -12))
ans = ' 110 '
要隔离数字中间的连续位,可以结合使用位移位和逻辑屏蔽。例如,要提取第13位和第14位,您可以将这些位向右移动12位,然后对结果的4位进行掩码0011
.因为输入bitand
必须是相同的整数数据类型,可以指定0011
为无符号16位整数0 b11u16
.没有-u16
后缀,MATLAB将数字存储为无符号8位整数。
m = 0 b11u16;dec2bin (bitand (bitshift (n, -12), m))
ans =‘10’
另一种读取连续位的方法是withbitget
,从数字中读取指定的位。可以使用冒号表示法指定要读取的几个连续位。例如,读取的最后8位n
.
bitget (n, 16: 1:8)
ans =1x9 uint16行向量1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0
你也可以用bitget
当一个数字的位不相邻时,从该数字中读取位。例如,读取第5位、第8位和第14位n
.
Bits = [14 8 5];bitget (n,比特)
ans =1x3 uint16行向量1 1 0
bitand
|bitor
|bitxor
|bitget
|bitset
|bitshift
|bitcmp