C语言里的左移和右移运算

先说左移,左移就是把一个数的所有位都向左移动若干位,在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中,左移是逻辑/算术左移(两者完全相同),右移是算术右移,会保持符号位不变.实际应用中可以根据情况用左/右移做快速的乘/除运算,这样会比循环效率高很多.

来源于http://hi.baidu.com/todaygoodhujun/blog/item/b8c10dd15ae4dfd3572c8417.html

时间: 2024-10-12 17:07:21

C语言里的左移和右移运算的相关文章

关于位运算中左移和右移运算的问题

根据我之前的学习知识, <<   和   >>  运算的规则如下: <<:左移运算:就是把当前这个二进制数向左移动多少位,低位空出的补零.高位移出的舍弃 >>:右移运算:就是把当前这个二进制数向右移动多少位,高位空出的来,原来最高位是什么,就补什么,低位移除的舍弃. 看下面的问题: public class Demo { public static void main(String[] args) { int a = 123; int b = a >&

【转】C语言中的左移与右移

先说左移,左移就是把一个数的所有位都向左移动若干位,在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类型最左

[c语言]左移和右移

左移和右移都是位运算的概念.我们知道计算机是基于二进制保存数据的,因此左移和右移的概念十分重要.本文约定是32位的机器. [左移] 丢弃最高位,0补最低位 左移是把一个数按照二进制每位向左移动若干位,在c语言中用运算符 << 表示.例如: int x = 1; x = x << 2; //把x的值左移2位 1对应的二进制数为000……0001(前面一共31个0),左移2位之后变成000……0100,在十进制下为4.所以看起来左移n位相当于乘以2的n次方.(有符号数不完全适用,因为左

C语言位运算符:与、或、异或、取反、左移和右移

语言位运算符:与.或.异或.取反.左移和右移 位运算是指按二进制进行的运算.在系统软件中,常常需要处理二进制位的问题.C语言提供了6个位操作运算符.这些运算符只能用于整型操作数,即只能用于带符号或无符号的char,short,int与long类型. C语言提供的位运算符列表:运算符 含义 描述& 按位与 如果两个相应的二进制位都为1,则该位的结果值为1,否则为0| 按位或 两个相应的二进制位中只要有一个为1,该位的结果值为1^ 按位异或 若参加运算的两个二进制位值相同则为0,否则为1~ 取反 ~

【转】C语言位运算符:与、或、异或、取反、左移与右移详细介绍

转载自:http://www.jb51.net/article/40559.htm,感谢原作者. 以下是对C语言中的位运算符:与.或.异或.取反.左移与右移进行了详细的分析介绍,需要的朋友可以过来参考下 位运算是指按二进制进行的运算.在系统软件中,常常需要处理二进制位的问题.C语言提供了6个位操作运算符.这些运算符只能用于整型操作数,即只能用于带符号或无符号的char,short,int与long类型. C语言提供的位运算符列表:运算符 含义 描述& 按位与 如果两个相应的二进制位都为1,则该位

用C语言实现循环左移和循环右移

有天重建一段代码时,遇到了循环右移指令,不知道用C语言怎么实现,后来得到小伟指点,感谢.. me 15:56:38004BD2C9 8B55 F8 MOV EDX,DWORD PTR SS:[EBP-8]004BD2CC D1CA     ROR EDX,1004BD2CE 8955 F8 MOV DWORD PTR SS:[EBP-8],EDX me 15:57:16这样的汇编,怎么用C语言写出来呢?ROR循环右移 小伟 15:58:51等等,翻笔记中. 小伟 15:59:06#define

嵌入式C语言里的土豪们之除法与移位

土豪这个词用在接下来要出场的C语言再合适不过了.他们在嵌入式C语言里占尽了奢华,但是毕竟我们更需要一个节约型的微生态环境.在这里简单给大家分析一下嵌入式C语言编程时用到的除法与移位. 本文引用地址:http://www.eepw.com.cn/article/182359.htm 除法土豪 除法在嵌入式微处理器里可算是一个消耗大户,复杂的实现方式不仅占用了大师宝贵的计算时间而且精度有限情况下占用了大片的RAM.因此,常常在各类文章里看到,编程人员应该使用右移运算来代替除法.这个右移方法没有问题,

C语言学习笔记:16_位运算

/* * 16_位运算.c * * Created on: 2015年7月6日 * Author: zhong */ #include <stdio.h> #include <stdlib.h> /* 位运算: * 所谓的位运算是指以二进制位为对象的运算. * c语言中位运算符有: * & 按位与 * | 按位或 * ^ 按位异或 * ~ 按位取反 * << 左移 * >> 右移 * * 除了 ~ 按位取反运算符以外,均为二目运算符. 两边的运算对象

PHP 位移运算符(&lt;&lt;左移和&gt;&gt;右移)

位移运算符 << 位左移 左移运算的实质是将对应的数据的二进制值逐位左移若干位,并在空出的位置上填0,最高位溢出并舍弃.例 如 $a=10; $b=$a<<2; 则$b=40,根据手册描述可以看出位运算可以看出向左移一位,则是实现乘2运算.由于位移操作的运算速度比乘法的 运算速度高很多.因此在处理数据的乘法运算的时,采用位移运算可以获得较快的速度. 提示 将所有对2的乘法运算转换为位移运算,可提高程序的运行效率 示例: 以下三种表达方式是一个意思. $a = 1024; for($