精华内容
下载资源
问答
  • 移位运算C语言还提供了一组移位运算,以便向左或者向移动位模式。对于一个位表示为[xn-1,xn-2,…,x0]操作数x,C表达式x<有一个相应右移运算x>>k,但是它行为有点微妙。一般而言,机器支持两种...

    深入理解C语言中的移位运算

    说明:本文主要摘录自《深入理解计算机系统》第二章信息的表示与处理。

    移位运算:

    C语言还提供了一组移位运算,以便向左或者向右移动位模式。对于一个位表示为[xn-1,xn-2,…,x0]的操作数x,C表达式x<

    有一个相应的右移运算x>>k,但是它的行为有点微妙。一般而言,机器支持两种形式的右移:逻辑右移和算术右移。逻辑右移在左端补k个0,得到的结果是[0,…,0,xn-1,xn-2,…,xk]。算术右移是在左端补k个最高有效位的值,得到的结果是[xn-1,…,xn-1,xn-1,xn-2,…,xk]。这种做法看上去可能有点奇特,但是我们会发现它对有符号整数数据的运算非常有用。

    让我们来看一个例子,下面的表给出了对某些实例8位数据做不同的移位操作得到的结果。

    操作

    参数X

    [0110 0011]    [1001 0101]

    X<<4

    [0011 0000]    [0101 0000]

    X>>4(逻辑右移)

    [0000 0110]    [0000 1001]

    X>>4(算术右移)

    [0000 0110]    [1111 1001]

    斜体的数字表示的是最右端(左移)或最左端(右移)填充的值。可以看到除了一个条目之外,其他的都涉及填充0。唯一的例外是算术右移[10010101]的情况。因为操作数的最高位是1,填充的值就是1。

    C语言标准并没有明确定义应该使用哪种类型的右移。对于无符号数据(也就是以限定词unsigned声明的整型对象),右移必须是逻辑的。而对于有符号数据(默认的声明的整型对象),算术的或者逻辑的右移都可以。不幸的是,这就意味着任何假设一种或者另一种右移形式的代码都潜在着可移植性问题。然而,实际上,几乎所有的编译器/机器组合都对有符号数据使用算术右移,且许多程序员也都假设机器会使用这种右移。

    另一方面,Java对于如何进行右移有明确的定义。表达式x>>k会将x算术右移k个位置,而x>>>k会对x做逻辑右移。

    当移动k位,这里k很大时

    对于一个由w位组成的数据类型,如果要移动k≥w位会得到什么结果呢?例如,在一个32位机器上计算下面的表达式会得到什么结果:

    Int       lval = 0xFEDCBA98  << 32;

    int       lval = 0xFEDCBA98  >> 36

    unsigned  lval = 0xFEDCBA98u  >> 40;

    C语言标准很小心地规避了说明在这种情况下该如何做。在许多机器上,当移动一个w位的值时,移位指令只考虑位移量的低log2w位,因此实际上位移量就是通过计算k mod w得到的。例如,在一台采用这个规则的32位机器上,上面三个移位运算分别是移动0、4和8位,得到结果:

    Lval    0xFEDCBA98

    Aval    0xFEDCBA9

    Uval    0x00FEDCBA

    不过这种行为对于C程序来说是没有保证的,所以移位数量应该保持小于字长。另一方面,Java特别要求位移数量应该按照我们前面所讲的求模的方法来计算。

    与移位运算有关的操作符优先级问题

    常常有人会写这样的表达式1<<2+3<<4,其本意是(1<<2)+(3<<4)。但是在C语言中,前面的表达式等价于1<

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

    2019-10-11 21:13:50
    c语言的移位运算 移位运算分为算术移位,逻辑移位,循环移位 算术移位要保持数字做高位符号位不变 例如:10101010 算术左移一位:11010100 算术右移一位:10010101 逻辑移位就是按照左右移要求依次移位 例如:...

    c语言中的移位运算

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

    算术移位要保持数字的做高位符号位不变
    例如:10101010
    算术左移一位:11010100
    算术右移一位:10010101

    逻辑移位就是按照左右移的要求依次移位
    例如:10101010
    逻辑左移一位:01010100
    逻辑右移一位:01010101

    循环移位就是数字不变,左右循环
    例如:10101010
    循环左移一位:01010101
    循环右移一位:01010101

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


     

    深入理解C语言中的移位运算

    移位运算:

    C语言还提供了一组移位运算,以便向左或者向右移动位模式。对于一个位表示为[xn-1,xn-2,…,x0]的操作数x,C表达式x<<k会生成一个值,其位表示为[xn-k-1,xn-k-2,…,x0,0,…,0]。也就是说,x向左移动k位,丢弃最高的k位,并在右端补k个0。移位量应该是一个0~n-1之间的值。移位运算是从左至右可结合的,所以x<<j<<k等价于(x<<j)<<k。
    </k会生成一个值,其位表示为[xn-k-1,xn-k-2,…,x0,0,…,0]。也就是说,x向左移动k位,丢弃最高的k位,并在右端补k个0。移位量应该是一个0~n-1之间的值。移位运算是从左至右可结合的,所以x<<j<<k等价于(x<<j)<<k。

    有一个相应的右移运算x>>k,但是它的行为有点微妙。一般而言,机器支持两种形式的右移:逻辑右移和算术右移。逻辑右移在左端补k个0,得到的结果是[0,…,0,xn-1,xn-2,…,xk]。算术右移是在左端补k个最高有效位的值,得到的结果是[xn-1,…,xn-1,xn-1,xn-2,…,xk]。这种做法看上去可能有点奇特,但是我们会发现它对有符号整数数据的运算非常有用。

    让我们来看一个例子,下面的表给出了对某些实例8位数据做不同的移位操作得到的结果。

    操作

    参数X

    [0110 0011] [1001 0101]

    X<<4

    [0011 0000] [0101 0000]

    X>>4(逻辑右移)

    [0000 0110] [0000 1001]

    X>>4(算术右移)

    [0000 0110] [1111 1001]

    斜体的数字表示的是最右端(左移)或最左端(右移)填充的值。可以看到除了一个条目之外,其他的都涉及填充0。唯一的例外是算术右移[10010101]的情况。因为操作数的最高位是1,填充的值就是1。

    C语言标准并没有明确定义应该使用哪种类型的右移。对于无符号数据(也就是以限定词unsigned声明的整型对象),右移必须是逻辑的。而对于有符号数据(默认的声明的整型对象),算术的或者逻辑的右移都可以。不幸的是,这就意味着任何假设一种或者另一种右移形式的代码都潜在着可移植性问题。然而,实际上,几乎所有的编译器/机器组合都对有符号数据使用算术右移,且许多程序员也都假设机器会使用这种右移。

    对于如何区分逻辑右移和算术右移一般说来无符号整型采用逻辑右移;带符号整型采用算术右移。

     

    展开全文
  • 移位运算符是将数据看成二进制数,对其进行向左或向移动若干位的运算。位移位运算符分为左移和右移两种,均为双目运算符。第一运算对象是移位对象,第二个运算对象是所移二进制位数。位移位运算符的运算对象、...

    位移位运算符是将数据看成二进制数,对其进行向左或向右移动若干位的运算。位移位运算符分为左移和右移两种,均为双目运算符。第一运算对象是移位对象,第二个运算对象是所移的二进制位数。

    位移位运算符的运算对象、运算规则与结果、结合性如表2-16所示。

    移位时,移出的位数全部丢弃,移出的空位补入的数与左移还是右移花接木有关。如果是左移,则规定补入的数全部是0;如果是右移,还与被移位的数据是否带符号有关。若是不带符号数,则补入的数全部为0;若是带符号数,则补入的数全部等于原数的最左端位上的原数(即原符号位)。具体移位规则如下所示。

    位移位运算符的优先级如下:

    ·算术运算符 优先于 位移位运算符 优先于 关系运算符

    ·位移位运算符是同级别的,结合性是自左向右

    例如,设无符号短整型变量a为0111(对应二进制数为0000000001001001),

    则:a<<3 结果为01110(对应二进制数为0000001001001000),a不变

    a>>4 结果为04 (对应二进制数为0000000000000100),a不变

    又如,设短整型变量a为-4(对应二进制数为 1111111111111100),

    则:a<<3 结果为-32(对应二进制数为1111111111100000),a不变

    a>>4 结果为-1(对应二进制数为1111111111111111),a不变

    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

    i = i<< 1;

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

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

    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

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

    在很多系统程序中常要求在位(bit)一级进行运算或处理。C语言提供了位运算的功能, 这使得C语言也能像汇编语言一样用来编写系统程序。

    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━

    操作符 作用

    ────────────────────────────

    & 位逻辑与

    | 位逻辑或

    ^ 位逻辑异或

    - 位逻辑反

    >> 右移

    << 左移

    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━

    按位运算是对字节或字中的实际位进行检测、设置或移位, 它只适用于字符型和整数型变量以及它们的变体, 对其它数据类型不适用。

    我们要注意区分位运算和逻辑运算。

    1. 按位与运算 按位与运算符'&'是双目运算符。其功能是参与运算的两数各对应的二进位相与。只有对应的两个二进位均为1时,结果位才为1 ,否则为0。参与运算的数以补码方式出现。

    例如:9&5可写算式如下: 00001001 (9的二进制补码)&00000101 (5的二进制补码) 00000001 (1的二进制补码)可见9&5=1。

    按位与运算通常用来对某些位清0或保留某些位。例如把a 的高八位清 0 , 保留低八位, 可作 a&255 运算 ( 255 的二进制数为0000000011111111)。

    main(){

    int a=9,b=5,c;

    c=a&b;

    printf('a=%d\nb=%d\nc=%d\n',a,b,c);

    }

    2. 按位或运算 按位或运算符“|”是双目运算符。其功能是参与运算的两数各对应的二进位相或。只要对应的二个二进位有一个为1时,结果位就为1。参与运算的两个数均以补码出现。

    例如:9|5可写算式如下: 00001001|00000101

    00001101 (十进制为13)可见9|5=13

    main(){

    int a=9,b=5,c;

    c=a|b;

    printf('a=%d\nb=%d\nc=%d\n',a,b,c);

    }

    3. 按位异或运算 按位异或运算符“^”是双目运算符。其功能是参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。参与运算数仍以补码出现,例如 9^5可写成算式如下: 00001001^00000101 00001100 (十进制为12)

    main(){

    int a=9;

    a=a^15;

    printf('a=%d\n',a);

    }

    4. 求反运算 求反运算符~为单目运算符,具有右结合性。 其功能是对参与运算的数的各二进位按位求反。例如~9的运算为: ~(0000000000001001)结果为:1111111111110110

    5. 左移运算 左移运算符“<

    6. 右移运算 右移运算符“>>”是双目运算符。其功能是把“>> ”左边的运算数的各二进位全部右移若干位,“>>”右边的数指定移动的位数。例如:设 a=15,a>>2 表示把000001111右移为00000011(十进制3)。应该说明的是,对于有符号数,在右移时,符号位将随同移动。当为正数时, 最高位补0,而为负数时,符号位为1,最高位是补0或是补1 取决于编译系统的规定。

    main(){

    unsigned a,b;

    printf('input a number: ');

    scanf('%d',&a);

    b=a>>5;

    b=b&15;

    printf('a=%d\tb=%d\n',a,b);

    }

    请再看一例!

    main(){

    char a='a',b='b';

    int p,c,d;

    p=a;

    p=(p<<8)|b;

    d=p&0xff;

    c=(p&0xff00)>>8;

    printf('a=%d\nb=%d\nc=%d\nd=%d\n',a,b,c,d);

    }

    当进行按位与或时,最好使用16进制,在程序中这样表示:0x01 表示0000 0001

    所以,字符类型a的最高位强制1可以这样:a=a|0x80。其他的可以依次类推!

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

    千次阅读 2018-08-24 17:09:58
    运算符优先级 ~高于&...移位给引脚置位基本等同,移位符左边是需要移位的数字,右边是需要移位的位数。 1.直接用宏来置位、复位(最右边为第1位) # define SET_NTH_BIT(x,n) (x|(1&lt;&lt;(n-1))) # d...
  • C语言中有逻辑运算和算术运算两种操作,数据在内存中都是以二进制转换其补码存放。显然,直接使用位操作要比其他操作效率高,下面我们来通过一些 代码看一下两者区别: int a = -1; // 1111 1111 1111 1111 1111...
  • C语言 移位运算

    2018-12-28 01:53:28
    今天看到这样一行代码 int n =0xfffffffe; int z = n &gt;&gt; 1 ; int m =(unsigned int )n &gt;&gt; 1; printf("...问输出值是多少?...逻辑移位,按位进行左右移动,不关心数值...
  • 文章目录一、位运算符1.1按位取反1.2按位与1.3按位或1.4按位异或二、移位运算符2.1左移运算符2.2移运算符三、类型转换详解四、多种位运算实例分析一、位运算符1.1按位取反按位取反~:作用是按位将0变成1,1变成0;...
  • C语言中位移位运算符 位移位运算符 /rrj/cpp/cjz22.htm 位移位运算符是将数据看成二进制数对其进行向左或向移动若干位的运算移位运算符分为左移和右移两种均为双目运算符第一运算对象是移位对象第二个运算对象是...
  • C语言的移位操作符 位移位运算符是将数据看成二进制数,对其进行向左或向移动若干位的运算。位移位运算符分为左移和右移两种,均为双目运算符。第一运算对象是移位对象,第二个运算对象是所移的二进制位数。 ...
  • C语言的移位操作

    2011-01-19 10:24:00
    右移位运算符>>与左移位运算符是不对称。对左操作数进行移位取决于左操作数类型:(1)如果左操作数是无符号(或带符号非负数),则左边移入0;(2)如果左操作数是带符号负数,则实现者可以选择补0或者把左...
  • C语言位移运算

    2015-03-22 17:31:34
    C语言提供了一组位移运算,C表达式x会生成一个值,x向左移动k位,丢弃最高k位,并在右端补k个0,移位运算时从左至可结合,所以x等价于(x)。 还有一个相应右移运算x>>k,但它行为有点微妙,一般而言机器支持...
  • 计算机底层数据运算大多以二进制进行,所以作为一个程序员必须要了解移位运算C语言中左移和右移运算分别用 << 和 >> 表示。 需要注意C语言位移操作是算数位移,即右移时,左边用原该值...
  • k x向左移动k位位移运算 从左至可结合 x&lt;&lt;j&lt;&lt;k等价于(x&lt;&lt;j)&lt;&lt;k移运算符: x&gt;&gt;k x向移动k位 逻辑右移和算术右移。逻辑右移在左端...
  • C语言运算运算

    2010-08-24 10:44:00
    二、 移位运算 1.“”左移:左边位将从字头挤掉,右边空出位补0。左移几位,相当于乘以二几次方。 2.“>>”右移:右边位将从字头挤掉,左边空出位若是正数补0,若是负数,可能补1或补0...
  • C语言中位移位运算符

    2010-03-31 16:28:00
    C语言中位移位运算符位移位运算符http://www.fsec.cn/rrj/cpp/cjz22.htm  位移位运算符是将数据看成二进制数,对其进行向左或向移动若干位的运算。位移位运算符分为左移和右移两种,均为双目运算符。第一运算...
  • C语言的位移运算

    千次阅读 2011-08-31 23:25:17
    C语言提供了一组位移运算,以便向左或向右... 还有一个相应的右移位运算x>>k,但是它的行为就有一点微妙了。一般而言机器支持两种右移位运算:一是算术位移,  另外一个是逻辑位运算。逻辑位运算就是左边补k个0,而算
  • Java的移位运算

    万次阅读 2020-11-01 01:14:28
    右移位运算却分为两种情况,分别是逻辑右移和算术右移(也叫无符号右移和符号右移),在逻辑右移中,会对操作数舍弃最低k位,并在左端补k个0,在算术运算中,则对操作数舍弃最低k位,并在左端补k个最高有效位...
  • 运算:最接近底层操作的运算。 左移:在右边补0 移位的时候,符号位不变,占据最高位,不参与移动。 右移:对于正数,可以把里面1全部移掉,直至全0. 对于有符号负数,右移,永远也不会变成全0...
  • C语言的移位操作符

    2017-04-21 08:57:11
    C语言的移位操作符   位移位运算符是将数据看成二进制数,对其进行向左或向移动若干位的运算。位移位运算符分为左移和右移两种,均为双目运算符。第一运算对象是移位对象,第二个运算对象是所移的二进制位数。 ...
  • 位运算主要是直接操控二进制时使用 ,主要目的是节约内存,使你程序...移位运算 要点 1 它们都是双目运算符,两个运算分量都是整形,结果也是整形。 2 " 左移:右边空出位上补0,左边位将从字头挤掉,其值相当

空空如也

空空如也

1 2 3 4 5 ... 12
收藏数 237
精华内容 94
关键字:

c语言的右移位运算

c语言 订阅