zoukankan      html  css  js  c++  java
  • 移位操作和二进制知识

    常用的移位操作是<< 和 >> ,分别为左移和右移。我们在C语言中有算数移位和逻辑移位两种。

    算数移位:区分符号的移位       {C语言中直接是定义char m = 3}

    逻辑移位:不区分符号的移位   {C语言中用unsigned char m = 3}

    算数移位和逻辑移位有什么不同,举例说明,例如:

    (1)对无符号数3来说:

    x<<1往左移一位,最左边的位移掉了,最右边的移进来的位补零。变成00000110,所以结果是6;[1*2^2 + 1*2^1 + 0*2^0 = 6]

    x>>1往右边移一位,由于是无符号数,所以逻辑右移,最右边一位移掉,最左边移进来的位补零,变成00000001,所以结果是1。[1*2^0 = 1]


    (2)对于有符号数3来说:

    x<<1往左移一位,最左边的位移掉了,最右边的移进来的位补零。变成00000110,所以结果是6;

    x>>1往右边移一位,由于是有符号数,可能发生逻辑右移,也可能发生算术右移,这一点,C标准并没有明确地指定是使用逻辑右移还是算术右移。但大多数的机器都使用算术右移,变成00000001,所以结果还是1。

    但是请注意,这只是说大多数的机器是这样的,你敢保证自己不会碰到特殊情况吗?


    (3)对于有符号数-3来说:

    x<<1往左移一位,最左边的位移掉了,最右边的移进来的位补零。变成11111010,结果是-6;[-(1*2^2 + 0*2^1 + 1*2^0 +1) = -6]

    x>>1往右移一位,由于是有符号数,可能发生逻辑右移,也可能发生算术右移。大多数机器使用算术右移,变成11111110,结果是-2。[-(1*2^0 +1) = -2]


    总结:

    左移时总是移位和补零;

    右移时无符号数是移位和补零,此时称为逻辑右移;

    而有符号数大多数情况下是移位和补最左边的位(也就是补最高有效位),移几位就补几位,此时称为算术右移。


    补充:

    1.汇编语言中的逻辑右移(SHR)是将各位依次右移指定位数,然后在左侧补0,算术右移(SAR)是将各位依次右移指定位数,然后在左侧用原符号位补齐
    2.高级语言右移运算符(>>)是将一个数的二进位全部右移若干位,低位移出部分舍弃,左补0
    3.高级语言右移和汇编语言中的逻辑右移功能一样,但不同于算术右移

    理解有误的认知:对于有符号整型数的简单认识就是:最高位为符号位,0为正,1为负。那么剩下几位应该如何表示呢?理所当然的认为:既然是1表示为0000 0001(假设为8位整型数,下同),那么-1就应该表示为1000 0001了。

    实际上在C语言里,-1的正确表示应该是1111 1111,即0xFF。因为C语言里,对整型数是采用Two’s complement表示法,而前面我的理解则是Sign-Magnitude表示法(浮点数采用该法)。在Two’s complement表示法里,1000 0001表示的是-127。

    几个特殊值,比如:

    正值的最大表示为0111 1111,即127。[1*2^6 + 1*2^5 + 1*2^4 + 1*2^3 + 1*2^2 + 1*2^1 +1*2^0 = 127]

    负值的最小表示为1000 0000,即-128。[-(1*2^6 + 1*2^5 + 1*2^4 + 1*2^3 + 1*2^2 + 1*2^1 +1*2^0 + 1) = -128]

    并因此带来几个有趣的现象,比如从8位有符号数转成16位有符号数的填充问题。以前想当然的是填0,但这是错的,应该是填充符号位的值。比如-1=0xFF填充符号位1就应该变成0xFFFF。而如果填充的是0,那么变成0x80FF就不对了。

    Two’s complement是不对称的。一个数的正负值表示,除了最高位之外,其余位数也是不尽相同的。在C语言里,当在无符号数和有符号数之间进行转换的时候,数值的二进制序列是不会改变的,改变的只是对该序列的解读模式。比如有符号数-1转换成无符号数就变成了255,虽然其二进制表示都是0xFF。如果不理解这一点,就会出Bug。

  • 相关阅读:
    SQL 行转列查询汇总
    c#中的委托是什么,事件是不是一种委托
    添加动画(两种)
    Follow 在地图中使地图和人物一起运动
    动作加速度Speed
    动作回调函数 (CallFunc,CallFuncN,CCCallFuncND)
    精灵沿着正方形路线运动暂停2秒后然后再将自己放大4倍
    CardinalSpline样条曲线(沿着正方形路线走)
    cocos2dx 3.2 Scale9Sprite点九图
    Label(标签)
  • 原文地址:https://www.cnblogs.com/huangjianwu/p/4549085.html
Copyright © 2011-2022 走看看