主要内容

位操作操作

本主题展示了如何在MATLAB®中使用逐位运算来操作数字的位。大多数现代cpu都直接支持对位的操作。万博1manbetx在许多情况下,以这种方式操作数字的位比执行除法或乘法等算术运算要快。

数字表示

任何数字都可以用位表示(也称为二进制数字).一个数的二进制形式,或以2为基数的形式,包含1和0,以表示该数中存在2的哪个乘方。例如,8位二进制形式的7是

00000111

8位的集合也称为1字节.在二进制表示法中,比特是从右到左计数的,所以在这种表示法中第一个比特是1。这个数字代表7,因为

2 2 + 2 1 + 2 0 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的补码位模式:

  1. 从数字的正数版本8的位模式开始:00001000

  2. 接下来,翻转所有位:11110111

  3. 最后,在结果中添加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有几个函数,使您能够对数字的两个等长二进制表示的位执行逻辑操作,称为位屏蔽

  • bitand——如果这两个数字是1,那么得到的数字也是1。否则,得到的数字是0。

  • bitor——如果要么Digit是1,那么结果也是1。否则,得到的数字是0。

  • bitxor—如果不相同,则得到的数字为1。否则,得到的数字是0。

除了这些函数外,按位补码也可用bitcmp,但这是一个一元操作,每次只换一个数的位。

位屏蔽的一个用途是查询特定位的状态。例如,如果您对二进制数使用逐位的AND操作00001000,可查询第4位的状态。然后,您可以将该位移到第一个位置,以便MATLAB返回0或1(下一节将更详细地描述位移)。

n = 0 b10111001;陶瓷= bitand (n, 0 b1000);陶瓷= bitshift(陶瓷,3)
陶瓷=uint81

按位操作可以有令人惊讶的应用。例如,考虑数字的8位二进制表示 n 8

00001000

8是2的幂,所以它的二进制表示只包含一个1。现在考虑一下这个数字 n - 1 7

00000111

通过减去1,从最右边的1开始的所有位都翻转了。因此,当 n 是2的幂,对应的数字是 n n - 1 总是不同的,按位排列的and返回0。

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

然而,当 n 不是2的幂,那么最右边的1是 2 0 一点,所以 n n - 1 所有的比特都一样,除了 2 0 一些。对于这种情况,按位计算的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位数。这个等价于一个通过 2 N

  • bitshift (A - n)移动一个正确的通过N位数。这个等价于一个通过 2 N

这些操作有时是写出来的< < N(左移)和一个> > N(右移),但MATLAB不使用<<>>操作符。

当一个数字的位移位时,一些位会从这个数字的末尾脱落,然后0年代或1S被引入来填充新创建的空间。当你向左移动位时,右边的位就会被填满;当你向右移动位时,左边的位就被填满了。

例如,如果你移动数字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

阅读Nonconsecutive比特

你也可以用bitget当一个数字的位不相邻时,从该数字中读取位。例如,读取第5位、第8位和第14位n

Bits = [14 8 5];bitget (n,比特)
ans =1x3 uint16行向量1 1 0

另请参阅

||||||

相关的话题