type
status
date
slug
summary
tags
category
icon
password
文章筛选
C语言位操作
一、常用位操作符
位与& | 无符号数 | 有符号数 |
位或| | 逻辑左移<< | 算数左移<< |
位异或^ | 逻辑右移>> | 算数右移>> |
位取反~ | ㅤ | ㅤ |
1、位与
真值表:
& | 0 | 1 |
0 | 0 | 0 |
1 | 0 | 1 |
3 & 5 = ?0b0011 (3)& 0b0101 (5)= 0b0001 (1)
拓展:&(按位与)与&&(逻辑与)的区别:
逻辑与是将运算的俩个数看做一个整体,而整体结果如果位0,则该数被定义成逻辑假(0);如果该数不为0(不管是正的还是负的),则被定义为逻辑真(1)。
2、位或(|)
真值表:
| | 0 | 1 |
0 | 0 | 1 |
1 | 1 | 1 |
3 | 5 = ?0b0011 (3)| 0b0101 (5)= 0b0111 (7)
拓展:&(按位或)与&&(逻辑或)的区别:
逻辑或是将运算的俩个数看做一个整体,而整体结果如果位0,则该数被定义成逻辑假(0);如果该数不为0(不管是正的还是负的),则被定义为逻辑真(1)。
3、位取反(~)
将操作数的二进制数的位逐个按位取反(1变0,0变1)。
真值表如下:
~1 = 0
~0 = 1
拓展:~(位取反)与!(非)的区别:
!(非)是将操作数整体看成一个整体,而这个整体如果是0,则该数被定义成逻辑假(0);如果该数不为0,(不管是正还是负的),则被定义成逻辑真(1)。
上面是正常的计算取反的方法,但是在计算机中并不是这样的,需要使用下面的方法。
这里先说一下二进制在内存的存储:二进制数在内存中以补码的形式存储另外,正数的原码、补码和反码都相同在计算机中,二进制数在内存中以补码的形式存储,因此要求出其原来的值,就需要在对该数求其补码。正数的原码补码,反码都相同。从负数的原码求反码和补码解题方法和步骤
(1)保持符号位的1不变,将数字部分的每一位求反(1改为0,0改为1),就得到了反码。(2)在反码的末位上加1,即得到补码。
4、位异或(^)
俩个数如果结果不等,则其结果为1,相等为0.
真值表如下:
^ | 0 | 1 |
0 | 0 | 1 |
1 | 1 | 0 |
3 ^ 5 = ?0b0011 (3)^ 0b0101 (5)= 0b0110 (6)
5、左移位(<<)
左移位就是将一个操作数的各二进制位全部左移若干位,左边移出去的二进制位丢弃,右边突出的二进制位补0。
5 << 2 =?0b 0000 0101 (5)0b 0001 0100 (20)
每进行一次左移位,就是将原来的数乘2。 5x2x2=20
6、右移位(>>)
右移是将一个操作数的各个二进制位全部右移若干位,左边的二进制补0或补1,(如果操作数是无符号数或有符号整数就补0,如果是有符号负数就补1),右边的二进制位丢弃。
负数的存储是以补码的形式存储的,移位是对其负数对应的补码进行的移位,因此原来的数还要进行求原码。
-5 >> 2 = -20b1111 1011 (-5)右移一位 :0b11111101 (-3)右移俩位: 0b11111110 (-2)
二、位操作与寄存器
1、寄存器特定位清零用&
如果希望将一个寄存器的某些特定位变成0而不影响其他位,可以构造一个合适的1和0组成的数,和这个寄存器原来的值进行位与操作,就可以将特定位清零。假设原来32位的寄存器REG的值为0xAAAAAAAA 我们希望将bit9~bit16置为0而其他位不变,将这个数与0X0000 FF00进行位与即可。REG & = 0x0000 FF00
2、寄存器特定位置1用|
如果希望将一个寄存器的某些特定位变成1而不影响其他位,可以构造一个合适的1和0组成的数,和这个寄存器原来的值进行位或操作,就可以将特定位置1。假设原来32位的寄存器REG的值为0xAAAA00AA 我们希望将bit9~bit16置为1而其他位不变,将这个数与0X0000 FF00进行位或即可。REG | = 0x0000 FF00
3、寄存器特定位取反用~
如果希望将一个寄存器的某些特定位0变成1,1变成0,,即取反而不影响其他位,可以构造一个合适的1和0组成的数,和这个寄存器原来的值进行异或操作,就可以将特定位清零。假设原来32位的寄存器REG的值为0xAAAAAAAA 我们希望将bit9~bit16取反而其他位不变,将这个数与0X0000 FF00进行位异或即可。REG ^ = 0x0000 FF00
- 作者:也平凡
- 链接:https://www.990001.xyz/blog/ccccs
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。