首页 > 代码库 > [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位):78位二进制为: 0000 0111

如果用四个字节来表示整数(4个字节是32位):732位二进制为: 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