首页 > 代码库 > [C++基础]原码/反码/补码、二进制位运算
[C++基础]原码/反码/补码、二进制位运算
原码/反码/补码
编码 | 定义 | 实例 |
原码 | 最高位为符号位,“0”表示正,“1”表示负,其余位表示数值的大小。 | 【+100】原=01100100 【+0】原=00000000 【-100】原=11100100 【-0】原=10000000注意:在原码中,零有两种表示形式。 |
反码 | 正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位除外。 | 【+100】反=01100100 【+0】反=00000000 【-100】反=10011011【-0】反=11111111 注意:在反码中,零也有两种表示形式。 反码运算也不方便,通常用来作为求补码的中间过渡。 |
补码 | 正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位除外。 | 【+100】补=01100100 【+0】补=00000000 【-100】补=10011100 【-0】补=00000000 注意:在补码中,零有唯一的编码,【+0】补=【-0】补=00000000。 |
注:8位二进制反码的表示范围:-127~+127
为什么计算机一般采用补码表示法
原码、反码和补码是由于表示负数的三种方案,三种方案中,原码最适合与乘除类运算,补码适合于加减类运算,而反码则加减与乘除都不是很理想,由于加减运算的频率远高于乘除运算,所以多数计算机系统采用的是补码方案。所以所有计算机的加减运算都要将相应的数转换成补码,然后再进行运算
- 原码是数制转换的产物,用于合乎人类逻辑的数字转换。
- 反码是一种形式化的中间产物,没什么实际作用,我们看不懂,计算机也看不懂,它的意义在于衔接。
- 补码是形式化的产品,直接用于形式化的逻辑运算,是计算机的逻辑电路进行运算的基础
二进制位运算
如果用一个字节来表示整数(1个字节是8位):7的8位二进制为: 0000 0111
如果用四个字节来表示整数(4个字节是32位):7的32位二进制为: 0000 0000 0000 0000 0000 0000 0000 0111
位运算是指按二进制位进行的运算。
运算符 | 含义 | 功能 |
& | 按位与 | 如果两个相应的二进制位都为1,则该位的结果值为1;否则为0。 |
| | 按位或 | 两个相应的二进制位中只要有一个为1,该位的结果值为1。 |
∧ | 按位异或 | 若参加运算的两个二进制位同号则结果为0(假)异号则结果为1(真) |
~ | 取反 | ~是一个单目(元)运算符,用来对一个二进制数按位取反,即将0变1,将1变0。 |
<< | 左移 | 左移运算符是用来将一个数的各二进制位全部左移N位,右补0。 |
>> | 右移 | 表示将a的各二进制位右移N位,移到右端的低位被舍弃,对无符号数,高位补0。 |
位运算应用口诀 :清零取反要用与,某位置一可用或 ;若要取反和交换,轻轻松松用异或
实例:
功能 | 示例 | 位运算 |
去掉最后一位 | (101101->10110) | x >> 1 |
在最后加一个0 | (101101->1011010) | x < < 1 |
在最后加一个1 | (101101->1011011) | x < < 1+1 |
把最后一位变成1 | (101100->101101) | x | 1 |
把最后一位变成0 | (101101->101100) | x | 1-1 |
最后一位取反 | (101101->101100) | x ^ 1 |
把右数第k位变成1 | (101001->101101,k=3) | x | (1 < < (k-1)) |
把右数第k位变成0 | (101101->101001,k=3) | x & ~ (1 < < (k-1)) |
右数第k位取反 | (101001->101101,k=3) | x ^ (1 < < (k-1)) |
取末三位 | (1101101->101) | x & 7 |
取末k位 | (1101101->1101,k=5) | x & ((1 < < k)-1) |
取右数第k位 | (1101101->1,k=4) | x >> (k-1) & 1 |
把末k位变成1 | (101001->101111,k=4) | x | (1 < < k-1) |
末k位取反 | (101001->100110,k=4) | x ^ (1 < < k-1) |
把右边连续的1变成0 | (100101111->100100000) | x & (x+1) |
把右起第一个0变成1 | (100101111->100111111) | x | (x+1) |
把右边连续的0变成1 | (11011000->11011111) | x | (x-1) |
取右边连续的1 | (100101111->1111) | (x ^ (x+1)) >> 1 |
去掉右起第一个1的左边 | (100101000->1000) | x & (x ^ (x-1)) |
判断奇数 | (x&1)==1 |
|
判断偶数 | (x&1)==0 |