移位运算分为算术移位、逻辑移位、循环移位
算术移位
在算术移位中,通过改变数码位和小数点的相对位置,从而实现各个数码位的位权。
在各机器码的移位中,左移相当于 ×2,右移相当于 ÷2,但由于位数有限,会造成溢出,就无法精确的等效乘除法。
原码的算术移位
原码的算术移位,符号位不参与移位,由于小数点是相对固定的,所以将数码位进行左右移动
- 左移,高位舍弃,低位补
0- 如果舍弃的是
1,会出现严重误差 - 如果舍弃的是
0,相当于×2
- 如果舍弃的是
- 右移,低位舍弃,高位补
0- 如果舍弃的是
1,会出现精度问题 - 如果舍弃的是
0,相当于÷2
- 如果舍弃的是
例:
舍弃的是 0
00101010对应十进制为42- 左移一位
01010100对应十进制为84 - 右移一位
00010101对应十进制为21
- 左移一位
舍弃的是 1
01010101对应十进制为85- 左移一位
00101010对应十进制为42- 如果机器位数够,不用舍弃,我们来看下它移位后的值
010101010对应十进制为170 170和42两个值的误差太大了
- 如果机器位数够,不用舍弃,我们来看下它移位后的值
- 右移一位
00101010对应十进制为42- 不用舍弃,看下移位后的值
00101010.1对应十进制为42.5 42.5和42两个值只是精度误差
- 不用舍弃,看下移位后的值
- 左移一位
反码的算术移位
反码的算术移位
- 正数的反码算术移位和原码一样
- 负数的反码算术移位
- 左移,高位舍弃,低位补
1 - 右移,低位舍弃,高位补
1
- 左移,高位舍弃,低位补
例:
- 正数原码
00101010对应十进制为42- 反码
00101010- 左移一位
01010100 - 右移一位
00010101
- 左移一位
- 反码
- 负数原码
10101010对应十进制为-42- 反码
11010101- 左移一位
10101011 - 右移一位
11101010
- 左移一位
- 反码
为啥负数的反码在移位时是补 1 呢?
因为负数的反码是在原码的基础上取反,所以为了保证数值上的统一,原码移位时是补 0,那反码就补 1
补码的算术移位
补码的算术移位
- 正数的补码算术移位和原码相同
- 负数的补码算术右移
- 负数补码左移(同原码):低位补
0,高位舍弃 - 负数补码右移(同反码):高位补
1,低位舍弃
- 负数补码左移(同原码):低位补
例:
- 正数原码
00101010,对应十进制为42- 补码
00101010,- 左移一位:
01010100 - 右移一位:
00010101
- 左移一位:
- 补码
- 负数原码
10101010,对应十进制为-42- 补码
11010100- 左移一位:
10101000 - 右移一位:
11101010
- 左移一位:
- 补码
为啥负数补码移位会分情况呢?
可以从负数原码、反码、补码他们之间找规律,比如 -42:
- 原码:
10101010 - 反码:
11010101 - 补码:
11010110
从右边开始数到第一个 1 的地方,1(包括 1)的右边同原码一样,左边同反码一样
- 左移,右边同原码一样,在右边(低位)补
0 - 右移,左边同反码一样,在左边(高位)补
1
总结
| 码制 | 补代码 | |
|---|---|---|
| 正数 | 原码、反码、补码 | 0 |
| 负数 | 原码 | 0 |
| 负数 | 反码 | 1 |
| 负数 | 补码 | 左移补0 |
| 负数 | 补码 | 右移补1 |
逻辑移位
逻辑移位:可以看作是对“无符号数”的算术移位
- 右移:高位补 0,低位舍弃
- 左移:低位补 0,高位舍弃
循环移位
循环移位分为不带进位位和带进位位两种:
- 不带进位位:用移出的位放入空位
- 左移:最高位被移出,最低位是空位,将移出的值放入空位
- 右移:最低位被移出,最高位是空位,将移出的值放入空位
- 带进位位:用移出的位放入空位(移位带上进位位)
- 左移:进位位移出,数据位的最高位放入进位位,最低位是空位,将移出的值放入空位
- 右移:数据位的最低位移出,进位位放入数据位的最高位,进位位是空位,将移除的值放入空位
