移位运算

码界流光
• 阅读 1549

移位运算分为算术移位、逻辑移位、循环移位

算术移位

在算术移位中,通过改变数码位和小数点的相对位置,从而实现各个数码位的位权。

在各机器码的移位中,左移相当于 ×2,右移相当于 ÷2,但由于位数有限,会造成溢出,就无法精确的等效乘除法。

原码的算术移位

原码的算术移位,符号位不参与移位,由于小数点是相对固定的,所以将数码位进行左右移动

  • 左移,高位舍弃,低位补 0

    • 如果舍弃的是 1,会出现严重误差
    • 如果舍弃的是 0,相当于 ×2
  • 右移,低位舍弃,高位补 0

    • 如果舍弃的是 1,会出现精度问题
    • 如果舍弃的是 0,相当于 ÷2

例:

舍弃的是 0

  • 00101010 对应十进制为 42

    • 左移一位 01010100 对应十进制为 84
    • 右移一位 00010101 对应十进制为 21

舍弃的是 1

  • 01010101 对应十进制为 85

    • 左移一位 00101010 对应十进制为 42

      • 如果机器位数够,不用舍弃,我们来看下它移位后的值 010101010 对应十进制为 170
      • 17042 两个值的误差太大了
    • 右移一位 00101010 对应十进制为 42

      • 不用舍弃,看下移位后的值 00101010.1 对应十进制为 42.5
      • 42.542 两个值只是精度误差

反码的算术移位

反码的算术移位

  • 正数的反码算术移位和原码一样
  • 负数的反码算术移位

    • 左移,高位舍弃,低位补 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,高位舍弃

循环移位

循环移位分为不带进位位和带进位位两种:

  • 不带进位位:用移出的位放入空位

    • 左移:最高位被移出,最低位是空位,将移出的值放入空位
    • 右移:最低位被移出,最高位是空位,将移出的值放入空位
  • 带进位位:用移出的位放入空位(移位带上进位位)

    • 左移:进位位移出,数据位的最高位放入进位位,最低位是空位,将移出的值放入空位
    • 右移:数据位的最低位移出,进位位放入数据位的最高位,进位位是空位,将移除的值放入空位
      移位运算
点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
7个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Wesley13 Wesley13
3年前
java 二进制(原码 反码 补码),位运算,移位运算,约瑟夫问题
一.二进制,位运算,移位运算1.二进制对于原码,反码,补码而言,需要注意以下几点:(1).Java中没有无符号数,换言之,Java中的数都是有符号的;(2).二进制的最高位是符号位,0表示正数,1表示负数;(3).正数的原码,反码,补码都一样;(4).负数的反码它的原码符号位不变,其他位取反;(5).
Wesley13 Wesley13
3年前
java中的7个位运算运算符
位运算指的是针对整数的二进制进行的位移操作。位运算提供比算术运算更高的效率,但是位运算的代码可读性较差,建议所有使用位运算的地方写上注释。Java中提供7个位运算符用于位运算。左移(<<)左移运算是将操作数二进制值逐位左移若干位,左移过程中符号位不变,高位溢出则舍弃,低位则补0。范例结果范例结果00000001<<
Wesley13 Wesley13
3年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Stella981 Stella981
3年前
Python运算符大全
  一、Python的算术运算  Python的算术运算符与C语言类似,略有不同。包括加()、减()、乘(\)、除(/)、取余(%)、按位或(|)、按位与(&)、按位求补(~)、左移位(<<)、右移位()、单目求反()、幂运算(\\)、整除运算(//)、增强运算、增强矩阵乘法(@)。  增强运算是将算术运算符或逻辑运算符放到等号的左
Wesley13 Wesley13
3年前
C语言位运算
位运算应用口诀清零取反要用与,某位置一可用或若要取反和交换,轻轻松松用异或移位运算要点1它们都是双目运算符,两个运算分量都是整形,结果也是整形。        2"<<"左移:右边空出的位上补0,左边的位将从字头挤掉,其值相当于乘2。       3""右移:右边的位被挤掉。对于左边移出的空位,如果是正数则空
Wesley13 Wesley13
3年前
NEO从源码分析看UTXO交易
_0x00前言_社区大佬:“交易是操作区块链的唯一方式。”_0x01交易类型_在NEO中,几乎除了共识之外的所有的对区块链的操作都是一种“交易”,甚至在“交易”面前,合约都只是一个小弟。交易类型的定义在Core中的TransactionType中:源码位置:neo/Core/TransactionType
Stella981 Stella981
3年前
JavaScript 位运算笔记
之前一直以为,在js的位运算中,双精度浮点数在内部会先被转成32位整数,再执行位运算,然后再转为64位数值,因此效率极低。今天实验发现,对浮点执行位运算只会导致数值不准确,而不会导致效率低下,相比乘法,左移位要快66%(其实就是浮点运算与整数运算的差距)。以下结果在IE7~IE10上测试得出技巧1:移位运算比乘除法快(当因数是2的幂数)