原文地址:http://www.cnblogs.com/myblesh/articles/2431806.html

由于在飞控程序中执行效率对程序的影响相当大,所以一个好的运算效率很重要。左移右移比单纯的吃乘除更快。

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

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

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

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

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; //
int32
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 

C
语言中的移位操作,内容不多。不过有些地方你不注意,就疏忽了。 

  先做两个小题先。 

  (1)unsigned char x=3; 

  x<<1是多少?x>>1是多少? 

  (2)char x=3; 

  x<<1是多少?x>>1是多少? 

  (3)char x=-3; 

  x<<1是多少?x>>1是多少? 

  3写成二进制数是00000011-3写成二进制数是(补码)11111101 

  程序执行的时候,操作的是数值的编码表示,也就是数值在内存中的二进制表示。比如说,程序取-3的时候,就去取11111101 

  (1)对无符号数3来说,x<<1往左移一位,最左边的位移掉了,最右边的移进来的位补零。变成00000110,所以结果是6x>>1往右边移一位,由于是无符号数,所以逻辑右移,最右边一位移掉,最左边移进来的位补零,变成00000001,所以结果是1

  (2)对于有符号数3来说,x<<1往左移一位,最左边的位移掉了,最右边的移进来的位补零。变成00000110,所以结果是6x>>1往右边移一位,由于是有符号数,可能发生逻辑右移,也可能发生算术右移,这一点,C标准并没有明确地指定是使用逻辑右移还是算术右移。但大多数的机器都使用算术右移,变成00000001,所以结果还是1。但是请注意,这只是说大多数的机器是这样的,你敢保证自己不会碰到特殊情况吗? 

  (3)对于有符号数-3来说,x<<1往左移一位,最左边的位移掉了,最右边的移进来的位补零。变成11111010,结果是-6。往右移一位,由于是有符号数,可能发生逻辑右移,也可能发生算术右移。大多数机器使用算术右移,变成11111110,结果是-2 

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

  附打印内存中字节编码的代码

void print_char(char x) 



  unsigned char * bp=(unsigned char *)&x; 

  int size=sizeof(x); 

  for(int i=0; i<size; i++) 

       printf("%.2x", bp[i]); 

  printf("\n"); 

}  

自从看到一个命令在我的手下,蹦的一下------------我就笑了

【转载】c语言数据的左移右移的更多相关文章

  1. 嵌入式C开发---用循环实现左移右移

    //将n左移m位 int byte_to_left_move(int n , int m) { int i , ret = 1 ; if(n == 0 || n < 0) { return ; ...

  2. jQuery实现左移右移

    <html> <head> <meta charset="utf-8"> <title>完成左移右移</title> & ...

  3. [转载]GMT地形数据总结

    [转载]GMT地形数据总结     原文地址:GMT地形数据总结作者:Jason 转载:http://seisman.info/gmt-topo-grid-datas.html   目前接触到的地形数 ...

  4. EASYUI- EASYUI左移右移 GRID中值

    EASYUI左移右移 GRID中值 $("#addAll").click(function(){ var ids = []; var names = []; var srcrows ...

  5. R语言数据接口

    R语言数据接口 R语言处理的数据一般从外部导入,因此需要数据接口来读取各种格式化的数据 CSV # 获得data是一个数据帧 data = read.csv("input.csv" ...

  6. R语言数据的导入与导出

    1.R数据的保存与加载 可通过save()函数保存为.Rdata文件,通过load()函数将数据加载到R中. > a <- 1:10 > save(a,file='d://data/ ...

  7. [转载]ecmall语言包程序

    [转载]ecmall语言包程序 (-- ::) 转载▼ 标签: 转载 收藏了 原文地址:ecmall语言包程序作者:我思故我在 执行顺序 登陆后台后 最先执行的文件是 default.app.php ...

  8. python 左移右移 2个数交换

    左移右移的能够使得数字*2或者/2 那*3怎么办,就左移一位然后再+ 经典面试题: 1.交换2个数,不用temp   a=10  b=12 1.1 a = a + b = 22 b = a - b = ...

  9. select多选左移右移的实现

    <html> <head> <meta http-equiv="Content-Type" content="text/html; char ...

随机推荐

  1. 1724: [Usaco2006 Nov]Fence Repair 切割木板

    1724: [Usaco2006 Nov]Fence Repair 切割木板 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 854  Solved: 42 ...

  2. Codevs2018 反病毒软件

    2018 反病毒软件 时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond  查看运行结果   题目描述 Description 其实这个“反病毒软件”(Anti ...

  3. Firefox52非HTTPS页面登录页面提示连接不安全的解决办法

    背景: Firefox52版本开始,对于非HTTPS协议的登录页面,会提示链接不安全,如下图 解决办法很简单,上HTTPS协议(严重推荐,尤其是祖国这种特殊国情下,上HTTPS的协议好处多多,物超所值 ...

  4. ZooKeeper的简单理解

    1 ZooKeeper的一致性特点 概念 描述 备注 顺序一致性 以ZXID来保证事务的顺序性 原子性 以ZAB保证原子操作,要么成功,要么失败 单一视图 无论客户端从哪个服务器获取到关于应用的数据都 ...

  5. 对象作为 map 的 key 时,需要重写 equals 方法和 hashCode 方法

    对象作为 map 的 key 时,需要重写 hashCode 和 equals方法 如果没有重写 hashCode 方法,那么下面的代码示例会输出 null 我们首先定义一个对象:BmapPoint, ...

  6. java内部发送http请求并取得返回结果,修改response的cookie

    public Object userLogin(HttpServletRequest request, HttpServletResponse response, String email, Stri ...

  7. React-Native 之 项目实战(二)

    前言 本文有配套视频,可以酌情观看. 文中内容因各人理解不同,可能会有所偏差,欢迎朋友们联系我. 文中所有内容仅供学习交流之用,不可用于商业用途,如因此引起的相关法律法规责任,与我无关. 如文中内容对 ...

  8. [原创]HBase学习笔记(4)- 数据导入

    需要分别从Oracle和文本文件往HBase中导入数据,这里介绍几种数据导入方案. 1.使用importTSV导入HBase importTSV支持增量导入.新数据插入,已存在数据则修改. 1.1.首 ...

  9. iOS开发之数据存储之Core Data

    1.概述 Core Data框架提供了对象-关系映射(ORM)的功能,即能够将OC对象转化成数据,保存在SQLite3数据库文件中,也能够将保存在数据库中的数据还原成OC对象.在此数据操作期间,不需要 ...

  10. java封装的方法

    java封装是由Java是面向对象程序设计语言的性质决定的,面向对象程序设计语言的三大特性之一就是封装.封装其实就是包装的意思,从专业的角度来看,就是把对象的所有组成部分组合在一起,保护私有属性. 如 ...