[转]位运算
原文:http://www.cnblogs.com/c2303191/articles/914074.html?login=1#commentform
5.按位逻辑运算的应用
例3-8:设 int x=7,求y=~x
y=~x=~7=~(0000,0000,0000,0111)=1111,1111,1111,1000=-8
可见,对x的值(7)按位求反结果恰为-8的补码表示,其原因是计算机中有:
整数求负=整数求补=按位求反+1
所以:按位求反=整数求负-1。
请注意求反运算与单目减和逻辑非运算的区别:
y=-x; 结果为:y=-7,
y=!x; 结果为:y=0。
例3-9:用按位与运算屏蔽特定位(将指定位清为0)。
设 n=051652(八进制数),计算m=n&0177,则:m=052。
n: 0,101,001,110,101,010
& 0177: 0,000,000,001,111,111
m: 0,000,000,000,101,010
经过位与运算,将n前9位屏蔽掉,即截取n的后7位。
例3-10:用按位与运算保留特定位。
要想将一个变量n的特定位保留下来,只要设一个数,使该数的某些位为1,这些位是与要保留的n的特定位相对应的位,再将n与该数按位与。
设 n=011050(为八进制数。对应的二进制为:0,001,001,000,101,000),要将n的右起第2、4、6、8、10位保留下来,只要 n=n&01252,则有:
n: 0,001,001,000,101,000
& 01252: 0,000,001,010,101,010
n: 0,000,001,000,101,000 (n=01050)
注意,按位与的"&"功能与取地址运算的"&"不同,尽管两者采用了相同的符号。
例3-11:用按位或运算将指定的位置为1。
设:x=061,y=016,则z=a|b为:
x: 0000,0000,0011,0001
| y: 0000,0000,0000,1110
z: 0000,0000,0011,1111
即将x或y中为1的位的相应位置成1,其结果是z中的后6位为1。
例3-12:用按位异或运算将某个量的特定位翻转。
要将变量n的特定位翻转,即原来为1的变0,为0的变1,只要设一个数,使该数的某些位为1,这些位是与n中要翻转的相对应的位,然后将n与该数进行按位异或运算。
设:a=015,要将后四位翻转,只要a=a^017,则:
a: 0000,0000,0011,1101
^ 017: 0000,0000,0011,1111
a: 0000,0000,0000,0010
3.5.3 移位运算
C语言提供了两个移位运算:左移和右移,它们是把整数作为二进制位序列,求出把这个序列左移若干位或者右移若干位所得到的序列。左移和右移都是双目运算,
运算符左边的运算对象是被左移或右移的数据,而运算符右边的运算对象是指明移动的位数。数据左移或右移后空出来的位置补0。
左移、右移运算表达式的一般形式为:
x << n 或 x >> n
其中x为移位运算对象,是要被移位的量;n是要移动的位数。
左移运算的规则是将x的二进制位全部向左移动n位,将左边移出的高位舍弃,右边空出的位补0。右移是将x的各二进制位全部向右移动n位,将右边移出的低位
舍弃,左边高位空出要根据原来量符号位的情况进行补充,对无符号数则补0;对有符号数,若为正数则补0,若为负数则补1。
例如,设a=7,则:
b=a<<2 即:b=0000,0111<<2=0001,1100=28
c=a>>2 即:c=0000,0111>>2=0000,0001=1
左移的一个特殊用途是将整数值乘以2的幂,例如:左移运算表达式1<<4的计算结果是16,右移可以用于将整数值除乘2的幂。
3.5.4 位运算赋值运算符
位运算符与赋值运算符可以组成以下5种位运算赋值运算符:
&=、 |=、 >>=、 <<=、 ^=
由这些位运算赋值运算符可以构成位运算赋值表达式。例如:
x&=y 相当于:x=x&y
x<<=2 相当于:x=x<<2
x>>=3 相当于:x=x>>3
x^=5 相当于:x=x^5
原码、补码和反码
(1)原码表示法
原码表示法是机器数的一种简单的表示法。其符号位用0表示正号,用:表示负号,数值一般用二进制形式表示。设有一数为x,则原码表示可记作[x]原。
例如,X1= +1010110
X2= 一1001010
其原码记作:
[X1]原=[+1010110]原=01010110
[X2]原=[-1001010]原=11001010
原码表示数的范围与二进制位数有关。当用8位二进制来表示小数原码时,其表示范围:
最大值为0.1111111,其真值约为(0.99)10
最小值为1.1111111,其真值约为(一0.99)10
当用8位二进制来表示整数原码时,其表示范围:
最大值为01111111,其真值为(127)10
最小值为11111111,其真值为(-127)10
在原码表示法中,对0有两种表示形式:
[+0]原=00000000
[-0] 原=10000000
(2)补码表示法
机器数的补码可由原码得到。如果机器数是正数,则该机器数的补码与原码一样;如果机器数是负数,则该机器数的补码是对它的原码(除符号位外)各位取反,并在未位加1而得到的。设有一数X,则X的补码表示记作[X]补。
例如,[X1]=+1010110
[X2]= 一1001010
[X1]原=01010110
[X1]补=01010110
即 [X1]原=[X1]补=01010110
[X2] 原= 11001010
[X2] 补=10110101+1=10110110
补码表示数的范围与二进制位数有关。当采用8位二进制表示时,小数补码的表示范围:
最大为0.1111111,其真值为(0.99)10
最小为1.0000000,其真值为(一1)10
采用8位二进制表示时,整数补码的表示范围:
最大为01111111,其真值为(127)10
最小为10000000,其真值为(一128)10
在补码表示法中,0只有一种表示形式:
[+0]补=00000000
[+0]补=11111111+1=00000000(由于受设备字长的限制,最后的进位丢失)
所以有[+0]补=[+0]补=00000000
(3)反码表示法
机器数的反码可由原码得到。如果机器数是正数,则该机器数的反码与原码一样;如果机器数是负数,则该机器数的反码是对它的原码(符号位除外)各位取反而得到的。设有一数X,则X的反码表示记作[X]反。
例如:X1= +1010110
X2= 一1001010
[X1]原=01010110
[X1]反=[X1]原=01010110
[X2]原=11001010
[X2]反=10110101
反码通常作为求补过程的中间形式,即在一个负数的反码的未位上加1,就得到了该负数的补码。
例1. 已知[X]原=10011010,求[X]补。
分析如下:
由[X]原求[X]补的原则是:若机器数为正数,则[X]原=[X]补;若机器数为负数,则该机器数的补码可对它的原码(符号位除外)所有位求反,再在未位加1而得到。现给定的机器数为负数,故有[X]补=[X]原十1,即
[X]原=10011010
[X]反=11100101
十) 1
[X]补=11100110
例2. 已知[X]补=11100110,求[X]原。
分析如下:
对于机器数为正数,则[X]原=[X]补
对于机器数为负数,则有[X]原=[[X]补]补
现给定的为负数,故有:
[X]补=11100110
[[X]补]反=10011001
十) 1
[[X]补]补=10011010=[X]原
作者:NewSea 出处:http://newsea.cnblogs.com/
QQ,MSN:iamnewsea@hotmail.com 如无特别标记说明,均为NewSea原创,版权私有,翻载必纠。欢迎交流,转载,但要在页面明显位置给出原文连接。谢谢。 |