【转载】c语言数据的左移右移
原文地址:http://www.cnblogs.com/myblesh/articles/2431806.html
由于在飞控程序中执行效率对程序的影响相当大,所以一个好的运算效率很重要。左移右移比单纯的吃乘除更快。
先说左移,左移就是把一个数的所有位都向左移动若干位,在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
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,所以结果是6;x>>1往右边移一位,由于是无符号数,所以逻辑右移,最右边一位移掉,最左边移进来的位补零,变成00000001,所以结果是1。
(2)对于有符号数3来说,x<<1往左移一位,最左边的位移掉了,最右边的移进来的位补零。变成00000110,所以结果是6;x>>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语言数据的左移右移的更多相关文章
- 嵌入式C开发---用循环实现左移右移
//将n左移m位 int byte_to_left_move(int n , int m) { int i , ret = 1 ; if(n == 0 || n < 0) { return ; ...
- jQuery实现左移右移
<html> <head> <meta charset="utf-8"> <title>完成左移右移</title> & ...
- [转载]GMT地形数据总结
[转载]GMT地形数据总结 原文地址:GMT地形数据总结作者:Jason 转载:http://seisman.info/gmt-topo-grid-datas.html 目前接触到的地形数 ...
- EASYUI- EASYUI左移右移 GRID中值
EASYUI左移右移 GRID中值 $("#addAll").click(function(){ var ids = []; var names = []; var srcrows ...
- R语言数据接口
R语言数据接口 R语言处理的数据一般从外部导入,因此需要数据接口来读取各种格式化的数据 CSV # 获得data是一个数据帧 data = read.csv("input.csv" ...
- R语言数据的导入与导出
1.R数据的保存与加载 可通过save()函数保存为.Rdata文件,通过load()函数将数据加载到R中. > a <- 1:10 > save(a,file='d://data/ ...
- [转载]ecmall语言包程序
[转载]ecmall语言包程序 (-- ::) 转载▼ 标签: 转载 收藏了 原文地址:ecmall语言包程序作者:我思故我在 执行顺序 登陆后台后 最先执行的文件是 default.app.php ...
- python 左移右移 2个数交换
左移右移的能够使得数字*2或者/2 那*3怎么办,就左移一位然后再+ 经典面试题: 1.交换2个数,不用temp a=10 b=12 1.1 a = a + b = 22 b = a - b = ...
- select多选左移右移的实现
<html> <head> <meta http-equiv="Content-Type" content="text/html; char ...
随机推荐
- App Store 审核 IPv6 问题
应用提交了N次,每次被拒都是说IPv6的事情,花点功夫把这个事情搞清楚. 苹果审核人员回复的原因都差不多,说在他们的IPv6-Only的环境中测试应用,无法正常请求我们的服务器. 因为我们的域名确实没 ...
- 关于IE低版本兼容问题
1,元素浮动之后,能设置宽度的话就给元素加宽度.如果需要宽度是内容撑开,就给它里边的块元素加上浮动: 解决方案:给需要宽度由内容撑开的元素加上浮动 css样式: <style> .box{ ...
- Oracle数据库笔记
SQL分为四大类别 1.DDL:Date Definition Language 数据定义语言 用于建立.修改.删除数据库对象(create创建表和其它对象结构:alter修改表或其它结构:drop ...
- 计算机程序的思维逻辑 (74) - 并发容器 - ConcurrentHashMap
本节介绍一个常用的并发容器 - ConcurrentHashMap,它是HashMap的并发版本,与HashMap相比,它有如下特点: 并发安全 直接支持一些原子复合操作 支持高并发.读操作完全并行. ...
- python 接口自动化测试--框架整改(五)
代码结构: 目标架构: 1.用例分析器,自动根据接口的参数,类型生成测试用例 2.数据分析器,自动维护接口参数数据,动态数据自动生成,返回结果自动查询判断 3.核心调用引擎,分SOAP和HTTP两种, ...
- HTML5学习笔记<二>:元素,属性,格式化
HTML元素 元素是指从开始标签到结束标签的所有代码. 开始(开放)标签 元素内容 结束(闭合)标签 <p> this is my web page </p> 没有内容的 HT ...
- eclipse一直报An internal error occurred during: "Building workspace". GC overhead limit exceeded
最近导入到eclipse里的工程挺大的,每次eclipse启动之后都回update workspace,然后就一直报: An internal error occurred during: " ...
- rip路由协议 细节分析及实例配置【完整版】
rip路由协议 细节分析及实例配置[完整版] RIP呢,这是一个比较重要的知识点,所以它的知识覆盖面很广泛:但是呢,我将会对碰到的问题进行一些分析解刨(主要是为了帮助自己理清思维):也希望能够从中发现 ...
- struts2(二) 表单参数自动封装和参数类型自动转换
前篇文章对struts2的一个入门,重点是对struts2的架构图有一个大概的了解即可,之后的几篇文章,就是细化struts2,将struts2中的各种功能进行梳理,其实学完之后,对struts2的使 ...
- git使用教程及github远程仓库管理
git使用教程步骤 1.安装git 安装完后,在开始菜单里找到"git"->"Git Bash",蹦出一个类似命令行窗口,说明安装成功.2 注册git 在 ...