数码的左右移位
学习三种移位方法后的总结:
逻辑移位:符号位也参与移动,简单了当进行移位;移位后产生的空位补零。|被挤出去的一般放入CF(进位标志)标志位,如果没有可以无视。
算术移位:在计算时发生的移位,操作对象是带符号数据,需要考虑符号位。在移位时移出去的位数直接丢弃,符号位不变。
为了方便查看直接列出一个更适合记忆的表格:
算术移位 | 类型 | 操作 |
正数 | 原码、反码、补码 | 左移右移都补零 |
负数 | 原码 | 左移右移都补零 |
补码 | 左移补0 | |
右移补1 | ||
反码 | 左移右移都补1 | |
在算数移位中,原码规则如下:
右移:高位补零,低位舍弃(丢精度)
左移:高位舍弃,低位补零(出误差)
反码规则:
处理反码时,要注意正数和负数的区别,正数的反码和原码处理方法一样,左移和右移的规则也和原码一样。对于负数:
右移:高位补1,低位舍弃
左移:低位补1,高位丢弃
(可以看到,负数时补的是1)
补码规则:
如上面所提到的,正数的原码、反码、补码三码相同,处理方式也一样。对于负数,它的处理方式和反码还有一些不同:
右移:同反码,低位舍弃,高位补1
左移:同原码,低位补0,高位舍弃
负数的补码和反码不同在于补码取反之后还要加1,进而导致进位。因此补码右侧一部分数位和原码肯定是一致的。处理方法也要看齐原码。
循环移位:被移走的数位转而被放置到另一端补充空位。高位被移出就补到低位,反之一样。
特别注意:有的数较为特殊,带有进数位CF,如果题目要求,移位的时候CF也要参与移动。在移动的时候,CF位视为在数位的最左侧参与移动。
------------------
以 0110 1110为例:
逻辑左移时,无论三码中任意一种,数据整体向左一位。最左侧的0直接丢弃,最低位补零。不考虑正负
0110 1110 -> 1101 1100
逻辑右移时,无论三码中任意一种,数据整体向右一位。右侧直接丢弃,最高位补零。不考虑正负
0110 1110 -> 0011 0111
------
另一种理解方式:
算术移位,需要考虑符号位。它的涵义是对一个数进行放大或缩小。符号位不可发生改变
1)
对于正数,三码相同,无论左移和右移都是直接补0。
2)
对于负数(标志位为1),需要分情况讨论:
原码中,左移负数发生溢出。
在补码中,算数左移时最右侧补0;算数右移时最左侧补1,也就是说移位时符号位也要参与移动,但是补齐时新符号位要和原符号一致。
1110 0110 -> 1111 0011
--------------
便于记忆,逻辑移位单纯移动数字,空位统统补零。
算数移位,符号位不动,正数均补零;负数右移 原码补零,其余补符号位;左移反码补1,其余补0。
另:在计算机内部,C语言等项目都以补码形式进行计算。正数补码不变,负数的补码是原码取反并末尾+1。而地址数是一个无符号整数。
原码在做乘除法的时候方便一些,但是加减法不方便,因为符号位不能参与运算,在计算原码加减法时,不止要考虑符号,还要考虑异号时两个数的绝对值大小,并且需要判断结果的符号。
参考:
https://zhuanlan.zhihu.com/p/97749860
王道21考研408