定点数的移位运算

定点数的移位运算

再开始学习如何计算如何乘除运算的时候,我们应该先了解一下定点数的移位运算

  • 先看一下十进制的移位运算
    123.456 → 小数点后移一位 1234.56 123.456\xrightarrow[]{小数点后移一位}1234.56 123.456小数点后移一位 1234.56 相当于 × 1 0 1 ×10^1 ×101
    123.456 → 小数点后移一位 12345.6 123.456\xrightarrow[]{小数点后移一位}12345.6 123.456小数点后移一位 12345.6 相当于 × 1 0 2 ×10^2 ×102
    123.456 → 小数点前移一位 12.3456 123.456\xrightarrow[]{小数点前移一位}12.3456 123.456小数点前移一位 12.3456 相当于 × 1 0 − 1 ×10^{-1} ×101

因为是十进制,所以在左右移位的时候进行 × 1 0 n ×10^n ×10n进行运算,那么同理,二进制也是相同原理,左移一位,如果不产生溢出,相当于乘以 2 2 2;右移一位,若不考虑因移出而舍去的末位尾数,相当于除以 2 2 2
移位分两种,为逻辑移位运算和算数移位

  • 逻辑移位
  • 逻辑移位操作将操作数视为无符号整数,规则是:左移时,高位移出,低位补零;右移时,低位移出,高位补零
  • 对于无符号整数的逻辑左移,若高位的 1 1 1移出,则发生溢出
    下面是将无符号数 11110 11110 11110进行移位 ( 8 8 8位)
原来 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0
右移 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1
左移 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0
  • 算术移位
  • 因为计算机中有符号的整数都是用补码表示的,因此对于有符号整数的移位操作采用补码算术移位方式,规则是:左移时,高位移出,低位补零,若移出的高位不同于移位后的符号位,则发生溢出;右移时,低位移出,高位补符号位,若低位的 1 1 1移出,则影响精度
  • 下面是将 − 30 -30 30 进行移位
符号位 2 6 2^6 26 2 5 2^5 25 2 4 2^4 24 2 3 2^3 23 2 2 2^2 22 2 1 2^1 21 2 0 2^0 20
1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0
右移一位 1 1 1 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1
再右移一位 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1

看出来第一次右移后转换成十进制为 − 15 -15 15 为原来数的一半
然而第二次有右移后出现了偏差,转成二进制后为 − 7 -7 7
原因是整数最低位往后会有一个小数点,不会占用任何位,接着就是小数位但是这是整数的算术移位所以会被舍弃

符号位 2 6 2^6 26 2 5 2^5 25 2 4 2^4 24 2 3 2^3 23 2 2 2^2 22 2 1 2^1 21 2 0 2^0 20 2 − 1 2^{-1} 21
右移两位后 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1小数点(不占位) 1 1 1

也就是 10000111.1 10000111.1 10000111.1转成十进制为 7.5 7.5 7.5
根据以上规律,当左移溢出的时候会出现严重的误差

符号位 2 6 2^6 26 2 5 2^5 25 2 4 2^4 24 2 3 2^3 23 2 2 2^2 22 2 1 2^1 21 2 0 2^0 20 转成十进制 转成十进制 转成十进制
1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 − 30 -30 30
左移一位 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 − 60 -60 60
左移二位 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 − 120 -120 120
左移三位 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 − 112 -112 112
  • [#]继续看定点小数的移位
    其实和整数都差不多
符号位 2 − 1 2^{-1} 21 2 − 2 2^{-2} 22 2 − 3 2^{-3} 23 2 − 4 2^{-4} 24 2 − 5 2^{-5} 25 2 − 6 2^{-6} 26 2 − 7 2^{-7} 27
1 1 1 0 0 0 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 0 0 0

左移一位

符号位 2 − 1 2^{-1} 21 2 − 2 2^{-2} 22 2 − 3 2^{-3} 23 2 − 4 2^{-4} 24 2 − 5 2^{-5} 25 2 − 6 2^{-6} 26 2 − 7 2^{-7} 27
1 1 1 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0

右移一位

符号位 2 − 1 2^{-1} 21 2 − 2 2^{-2} 22 2 − 3 2^{-3} 23 2 − 4 2^{-4} 24 2 − 5 2^{-5} 25 2 − 6 2^{-6} 26 2 − 7 2^{-7} 27
1 1 1 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0
反码与补码的移位
  • 正数的反码与补码移位和原码相同,这里主要介绍负数计算方法
    先写一下正数 12 12 12
符号位 2 6 2^6 26 2 5 2^5 25 2 4 2^4 24 2 3 2^3 23 2 2 2^2 22 2 1 2^1 21 2 0 2^0 20
原码 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0
反码 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0
补码 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0

下面是负数 − 12 -12 12

符号位 2 6 2^6 26 2 5 2^5 25 2 4 2^4 24 2 3 2^3 23 2 2 2^2 22 2 1 2^1 21 2 0 2^0 20
原码 1 1 1 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0
反码 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1
补码 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 1 1 0 0 0 0 0 0

规则是(从右往左找到第一个 1 1 1然后这个左边所有的数值位取反):

  • 右移:高位补 1 1 1,低位舍弃
  • 左移:低位补 1 1 1,高位舍弃

就是蓝色框起来的遵循负数移位规律,而黑色框起来的遵循正数移位规则
在这里插入图片描述
下面就将这个补码左移一位

符号位 2 6 2^6 26 2 5 2^5 25 2 4 2^4 24 2 3 2^3 23 2 2 2^2 22 2 1 2^1 21 2 0 2^0 20
补码 1 1 1 1 1 1 1 1 1 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0

右移一位

符号位 2 6 2^6 26 2 5 2^5 25 2 4 2^4 24 2 3 2^3 23 2 2 2^2 22 2 1 2^1 21 2 0 2^0 20
补码 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 1 1 0 0 0

这里我们可以验证一下,当左移一位得到的补码转换成原码是 10011000 10011000 10011000,转成十进制是 − 24 -24 24
右移一位转成原码是 10000110 10000110 10000110,转成十进制是 − 6 -6 6,验证正确.

  • 24
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值