精华内容
参与话题
问答
  • 移位运算用法总结

    万次阅读 多人点赞 2018-06-02 00:09:36
    二、移位运算 它们都是双目运算符,两个运算分量都是整形,结果也是整形。 ‘<<’左移:右边空出的位置补0,其值相当于乘以2。 ‘>>’右移:左边空出的位,如果是正数则补0,若为负数...

    位运算总结

    原文

    一、位运算应用口诀

    清零取位要用与,某位置一可用或
    若要取反和交换,轻轻松松用异或

    二、移位运算

    1. 它们都是双目运算符,两个运算分量都是整形,结果也是整形。
    2. ‘<<’左移:右边空出的位置补0,其值相当于乘以2。
    3. ‘>>’右移:左边空出的位,如果是正数则补0,若为负数则补0或1,取决于所用的计算机系统OS X中补1。其值相当于除以2。

    三、位运算符的应用(原操作数s掩码mask)

    1. 按位与&
      • 清零特定位(mask中特定位置0,其他位为1,s = s&mask)
      • 取某数中指定位(mask中特定位置1,其他位为0,s = s&mask)
    2. 按位或|
      常用来将原操作数某些位置1,其他位不变。(mask中特定位置1,其他位为0 s = s|mask)
    3. 位异或^
      • 使特定位的值取反(mask中特定位置1,其他位为0,s = s^mask)
      • 不引入第三变量,交换两个变量的值(设a = a1,b = b1,a^b^a = b)

    四、应用举例

    1. 判断整数a是奇数还是偶数
      • a&1 = 0 偶数
      • a&1 = 1 奇数
    2. 取整数a的第k位(k = 0,1,2,…len(str(a))),即a>>k&1
    3. 将int型变量a的第k位清0,即a=a&~(1<
            int average(int x, int y)   //返回X,Y 的平均值
            {   
                  return (x&y)+((x^y)>>1);
            }
    1. 判断一个整数是不是2的幂,对于一个数 x >= 0,判断他是不是2的幂
      boolean power2(int x)
      {
      return ((x&(x-1))==0)&&(x!=0);
      }

    9、不用temp交换两个整数

        void swap(int x , int y)
        {
             x ^= y;
             y ^= x;
             x ^= y;
        }
    

    10、计算绝对值

        int abs( int x )
        {
             int y ;
             y = x >> 31 ;
             return (x^y)-y ;        //or: (x+y)^y
         }
    
    11、取模运算转化成位运算 (在不产生溢出的情况下)
            a % (2^n) 等价于 a & (2^n - 1)
    12、乘法运算转化成位运算 (在不产生溢出的情况下)
            a * (2^n) 等价于 a<< n
    13、除法运算转化成位运算 (在不产生溢出的情况下)
            a / (2^n) 等价于 a>> n
            例: 12/8 == 12>>3
    14、a % 2 等价于 a & 1       
    15、if (x == a) x= b;
    

       else x= a;
       等价于 x= a ^ b ^ x;
    16、x 的相反数表示为 (~x+1)

    比较浅显的来说,左移n位就是乘以2的n次方,右移n位就是除以2的n次方。具体细节如下:

    C语言里的左移和右移运算
    2006-09-30 13:52

    先说左移,左移就是把一个数的所有位都向左移动若干位,在C中用<<运算符.例如:

    int i = 1;
    i = i << 2; //把i里的值左移2位

    也就是说,1的2进制是000…0001(这里1前面0的个数和int的位数有关,32位机器,gcc里有31个0),左移2位之后变成 000…0100,也就是10进制的4,所以说左移1位相当于乘以2,那么左移n位就是乘以2的n次方了(有符号数不完全适用,因为左移有可能导致符号变化,下面解释原因)

    需要注意的一个问题是int类型最左端的符号位和移位移出去的情况.我们知道,int是有符号的整形数,最左端的1位是符号位,即0正1负,那么移位的时候就会出现溢出,例如:

    int i = 0x40000000; //16进制的40000000,为2进制的01000000…0000
    // 40000000 共八位,故用二进制表示为32位。
    i = i << 1;

    那么,i在左移1位之后就会变成0x80000000,也就是2进制的100000…0000,符号位被置1,其他位全是0,变成了int类型所能表示的最小值,32位的int这个值是-2147483648,溢出.如果再接着把i左移1位会出现什么情况呢? (这个真不知道?????????)
    在C语言中采用了丢弃最高位的处理方法,丢弃了1之后,i的值变成了0.

    左移里一个比较特殊的情况是当左移的位数(>>32)超过该数值类型的最大位数时,编译器会用左移的位数去模类型的最大位数,然后按余数进行移位,如:

    int i = 1, j = 0x80000000; //设int为32位
    i = i << 33; // 33 % 32 = 1 左移1位,i变成2
    j = j << 33; // 33 % 32 = 1 左移1位,j变成0,最高位被丢弃

    在用gcc编译这段程序的时候编译器会给出一个warning,说左移位数>=类型长度.那么实际上i,j移动的就是1位,也就是33%32后的余数.在gcc下是这个规则,别的编译器是不是都一样现在还不清楚.

    总之左移就是: 丢弃最高位,0补最低位(不懂????)

    再说右移,明白了左移的道理,那么右移就比较好理解了.

    右移的概念和左移相反,就是往右边挪动若干位,运算符是>>.

    右移对符号位的处理和左移不同,对于有符号整数来说,比如int类型,右移会保持符号位不变,例如:

    int i = 0x80000000;
    i = i >> 1; //i的值不会变成0x40000000,而会变成0xc0000000

    就是说,符号位向右移动后,正数的话补0,负数补1,也就是汇编语言中的算术右移.同样当移动的位数超过类型的长度时,会取余数,然后移动余数个位.

     负数10100110 >>5(假设字长为8位),则得到的是  11111101  //前面三个101往右移5位;
    

    总之,在C中,左移是逻辑/算术左移(两者完全相同),右移是算术右移,会保持符号位不变.实际应用中可以根据情况用左/右移做快速的乘/除运算,这样会比循环效率高很多.

    unsigned char a;
    a=1; //0b00000001
    a<<=1; //0b00000010 a左移1位等效于a=a*2
    a<<=2; //0b00001000 a左移2位等效于a=a*2的2次方(4)
    a<<=3; //0b01000000 a左移1位等效于a=a*2的3次方(8)
    a<<=1; //0b10000010 a左移1位等效于a=a*2
    a<<=1; //0b00000000 a再次左移1位后溢出了,结果变成0了

    展开全文
  • 移位运算,所有移位以5和-5为例移位运算左移(<<)正数负数带符号右移(>>)(右移向前面补对应的符号位所对应的值(正数补0,负数补1))正数负数不带符号右移(>>>)(>>>为java独有语法)正数...

    移位运算

    可以移位运算的类型有:iuint,int,lang等类型.我们本次使用int类型
    一个int类型占4个字节,共32位,带符号位,所以最高位位符号位(使用0,1表示符号位)

    我们首先需要了解正数和负数的二进制码分别如何表示(以5和-5为例)

    正数:0000 0000 0000 0101
    负数:1000 0000 0000 0101

    移位操作在二进制中都是补码移位在转会为原码得到相应的值
    正数的反码,补码与原码相同
    负数的反码为除符号位全部取反
    负数的补码为反码加1

    所以 在对正数进行移位操作时就是对原码进行操作
    负数是对补码操作,操作完成后再转换为原码得到对应的值
    所以-5的补码为:1111 1111 1111 1011

    左移(<<)

    正数

     5左移三位:0000 0000 0010 1000 =40
    

    负数

    -5左移三位:补码:1111 1111 1101 0111
    原码:1000 0000 0010 1000
    得:-40

    带符号右移(>>)(右移向前面补对应的符号位所对应的值(正数补0,负数补1))

    正数

    5右移三位:0000 0000 0000 0000 =0

    负数

    -5右移三位:补码:1111 1111 1111 1111
    反码:1111 1111 1111 1110
    原码:1000 0000 0000 0001
    得:-1

    不带符号右移(>>>)(>>>为java独有语法)

    正数

    5右移三位:0000 0000 0000 0000 =0

    负数

    -5右移三位:补码:0001 1111 1111 1111 1111 1111 1111 1111
    反码:0001 f f f f f f 1110
    得:536 870 911

    展开全文
  • C 移位运算

    千次阅读 2019-06-26 14:16:04
    移位运算分为左移(<<)与右移(>>),包含逻辑移位(logical shift)和算术移位(arithmetic shift),二者区别如下: (1)逻辑移位:移出去的位丢弃,空缺位(vacant bit)用 0 填充; (2)算术移位...

    移位运算分为左移(<<)与右移(>>),其中右移又分为逻辑右移与算术右移。三者实现如下:
    (1)左移:移出去的位丢弃,空缺位(vacant bit)用 0 填充;
    (2)逻辑右移:移出去的位丢弃,空缺位(vacant bit)用 0 填充;
    (3)算术右位:移出去的位丢弃,空缺位(vacant bit)用符号位来填充。

    以补码 0x10110011 来演示左移、逻辑右移与算术右移。

    左移:
    在这里插入图片描述
    逻辑右移:
    在这里插入图片描述
    算术右移:
    在这里插入图片描述
    移位算只能作用于整数,不能作用于浮点数。对于无符号整数与有符号整数,左移操作相同,但右移稍有区别。
    (1)对于无符号整数为逻辑右移;
    (2)对于有符号整数为算术右移。

    注意, 对于无符号整数,右移必须是逻辑右移。而对于有符号整数,C 语言标准并没有明确定义应该使用哪种类型的右移,但几乎所有的编译器均采用算术右移。

    参考如下示例:

    //
    //@file: main.c
    //
    
    #include <stdio.h>
    #include <stdint.h>
    
    int main()
    {
            int a = -1;    
            printf("a=0x%x\n", a);          //a=0xffffffff          
            printf("a<<1=0x%x\n", a<<1);    //左移,结果为 0xfffffffe
            printf("a>>2=0x%x\n", a>>2);    //算术右移,结果为 0xffffffff
        
            unsigned int b=1;
            printf("b=0x%08x\n", b);        //b=0x00000001
            printf("b<<1=0x%08x\n", b<<1);  //左移,结果为 0x00000002
            printf("b>>1=0x%08x\n", b>>1);  //逻辑右移,结果为 0x00000000
    }
    

    编译输出结果:

    gcc main.c
    ./a.out
    
    a=0xffffffff
    a<<1=0xfffffffe
    a>>2=0xffffffff
    b=0x00000001
    b<<1=0x00000002
    b>>1=0x00000000
    

    参考文献

    [1] 龚奕利,贺莲译.深入理解计算机系统[M].北京:机械工业出版社,2016-11.C2.1.9 C语言中的移位运算.P40-41

    展开全文
  • c语言中的移位运算符

    万次阅读 2017-10-14 19:10:14
    移位运算符:  >> 右移运算符  一丶  移位规则:左边抛弃,右边补零

    数据在计算机中以补码存储   

    移位运算符:<<  左移运算符

                            >>  右移运算符

          一丶 << 左移运算符

                  移位规则:左边抛弃,右边补零

                  int num=10;

                  num<<1

                 00000000000000000000000000001010    num 在内存中的二进制

              00000000000000000000000000010100    num左移一位产生的结果

                num<<1 在num没有被赋值的情况下其值不变

                num=num<<1其值发生变化

          二丶>>右移运算符

                 移位规则:1.逻辑移位

                                         左边用0补充,右边丢弃;

                                     2.算术移位

                                         左边用原该值的符号位填充,右边丢弃。

                 int num=-1;

                 11111111111111111111111111111111  num在内存中存储

                  逻辑右移

                 01111111111111111111111111111111  1   

                 算术右移

                 11111111111111111111111111111111  1

            !!!!!! 移位运算符的操作数不能为负数:   num>>-1错误




    0

                    

          

    展开全文
  • C语言中的移位运算

    千次阅读 2018-09-19 15:03:20
    移位运算 移位运算包括左移和右移 左移运算: x&amp;lt;&amp;lt;k:x左移k位,并在右端补零。 右移运算: 逻辑右移: x&amp;gt;&amp;gt;k:x右移k位,并在左端补零。 算术右移: x&amp;gt;&...
  • 移位运算符

    2020-02-26 20:03:30
    '>>' 和 '<<' 都是位运算符的一种,都是直接对二进制位操作的运算符。'>>' 和 '<<' 的具体作用就是对二进制位进行移动操作,一般只能对整型变量进行...如下图,我们默认在8位下进行运算: ...
  • 移位运算

    2019-01-14 11:55:00
    一、位运算 (1)按 位 与 & 如果两个相应的二进制形式的对应的位数都为1,则结果为1,记为同1为1,否则为0。首先我们看一下对正数的运算 分别看一下正数和负数的具体运算步骤 正数直接取二进制运算,...
  • ”运算符执行左移位运算。在移位运算过程中,符号位始终保持不变。如果右侧空出位置,则自动填充为 0;超出 32 位的值,则自动丢弃。 运算 5 << 2 第一个数的位值 左移2位运算结果 0 1 0 0 1 1 ...
  • 移位运算符

    千次阅读 多人点赞 2019-05-12 10:51:16
    移位运算符(<<、>>、>>>)左移运算符(<<)正数负数右移运算符(>>)正数负数无符号右移运算符(>>>)正数负数 左移运算符(<<) 按二进制形式把所有的数字向左...
  • 【Java】移位运算

    千次阅读 2017-07-09 15:59:13
    以前一直没有研究二进制的移位运算的应用场景是什么,怎么运算?怎么实现数据的四则运算的? 直到最近,在看Think in Java的书籍,才真正理解这个东西。下面记录一下学习笔记。 1,二进制1.1 二进制的表示我们知道...
  • 移位运算(左移和右移)

    千次阅读 2014-04-05 11:33:29
    移位运算(左移和右移)   这是网上流传的“变态级JAVA程序员面试32问”的其中一题(二十八题),然后下面给出来的答案是   第二十八,编程题: 用最有效率的方法算出2乘以
  • java中的三种移位运算符>>>

    万次阅读 2018-06-12 21:25:31
    移位运算符 是位操作运算符的一种。移位运算符可以在二进制的基础上对数字进行平移。按照平移的方向和填充数字的规则分为三种:&lt;&lt;(左移)、&gt;&gt;(右移)和&gt;&gt;&gt;(无符号...
  • 移位运算

    2020-07-16 16:59:05
    移位运算 1.逻辑移位 2.算数移位 3.循环移位
  • 位运算与移位运算

    2018-04-01 16:42:19
    1 原码 原码就是直接将数转为二进制,对于有符号的数来说,用第一位表示符号,1表示负数,0表示正数。 其余位表示值。 [+1]原 = 0000 0001 [- 1]原 = 1000 0001 ...负数的反码:符号位不变,其他位按位取反。...
  • 移位运算

    2016-12-07 22:40:49
    int num=32; System.out.println(num>>32); 一、java中有三种移位运算符 左移运算符,num ,相当于num乘以2 >> : 右移运算符,num >> 1,...在移位运算时,byte、short和char类型移位后的结果会变成int类型,对于
  • Java 的移位运算

    千次阅读 2016-06-15 14:17:01
    在Think in Java中有这么一段话“对char,byte或者short进行移位处理,那么在移位进行之前,它们会自动转换成一个int。只有右侧的5个低位才会有用。这样可防止我们在一个int数里移动不切实际的位数。若对一个long值...
  • 逻辑运算与移位运算

    2012-11-27 14:56:55
    [code="java"]源码:正数的补码与原码相同例+7 源码:00000111 补码 :00000111 (用8位二进制表示一个数) [/code] [code="java"]负数的补码: ... 符号位为1,其余位为该数绝对值的原码按位...
  • 移位运算

    千次阅读 2011-04-19 22:38:00
    C++位运算,看高手都是运用的灵活自如,打算从今天开始学习他!收藏 每次看到位运算的地方,都比较迷糊.以前学习C的时候也不求甚解,到现在看来,觉得位运算和指针在C++基本知识里是最难理解,最难融会贯通的东西.尤其是位...
  • 位运算和移位运算

    2018-07-26 14:39:36
    一、位运算位运算符包括: 与(&amp;amp;)、非(~)、或(|)、异或(^) &amp;amp;:当两边操作数的位同时为1时、结果为1、否则为0、如1100&amp;amp;1010=1000 ~:当两边操作数的位有一边为1时、结果...
  • 深入理解C语言中的移位运算

    千次阅读 2014-04-24 20:26:21
    C语言还提供了一组移位运算,以便向左或者向右移动位模式。对于一个位表示为[xn-1,xn-2,…,x0]的操作数x,C表达式x 有一个相应的右移运算x>>k,但是它的行为有点微妙。一般而言,机器支持两种形式的右移:逻辑...

空空如也

1 2 3 4 5 ... 20
收藏数 57,531
精华内容 23,012
关键字:

移位运算