计算机原理与基础 —— C语言中的左移与右移
1、双目运算符
位移位运算符是将数据看成二进制数,对其进行向左或向右移动若干位的运算。
位移位运算符分为左移和右移两种,均为双目运算符。
例如: 8 >> 3 (意思是8向右移动3位)第一运算对象是移位对象,第二个运算对象是所移的二进制位数。
2、逻辑移位与算术移位
在嵌入式开发中,移位操作是常用的一种运算。但是在进行移位运算的时候,如果没有考虑到有符号和无符号的移位区别,就很容易掉进陷阱,得不到我们想要的结果。
我们可以看下面例子,你们猜出结果么?
signedchar i = -125;
i= i >> 2;
cout<< (int)i;
return 0;
编译结果为:-32
为什么有这样的结果?首先介绍两个概念:逻辑移位和算数移位。
逻辑移位,简单理解就是物理上按位进行的左右移动,两头用0进行补充,不关心数值的符号问题。
算术移位,同样也是物理上按位进行的左右移动,两头用0进行补充,但必须确保符号位不改变。
算术移位指令
算术移位指令有:算术左移SAL(ShiftAlgebraic Left)和算术右移SAR(ShiftAlgebraic Right)。算术移位指令的功能描述如下:
(1)算术左移SAL把目的操作数的低位向高位移,空出的低位补0;
(2)算术右移SAR把目的操作数的高位向低位移,空出的高位用最高位(符号位)填补。
逻辑移位指令
此组指令有:逻辑左移SHL(ShiftLogical Left)和逻辑右移SHR(ShiftLogical Right)。逻辑左移/右移指令只有它们的移位方向不同,移位后空出的位都补0。
(1) 逻辑左移SHL
(2) 逻辑右移SHR
但我们好奇的是“i<<3”和“i>>3”到底采用的是算术还是逻辑移位呢?
首先了解一下《计算机原理及基础 —— 有符号类型和无符号类型》
通过sizeof查看在计算机中用几字节存储的,即8在计算机内是以0000 1000 形式还是以 0000 0000 0000 1000形式!
其次了解一下 《原码、反码、补码之间的快速转换和简单运算》
查看有符号、无符号类型左移或者右移后的数值是多少!
左移
1、当向左边移动3位,采用的什么方式的移动???
#include <stdio.h>
int main()
{unsigned int ui = 8;ui = ui << 3;printf("ui = %d 无符号类型左移(正数)\n", ui);printf("sizeof(unsigned int ) = %d\n", sizeof(unsigned int));int i = 8;i = i << 3;printf("i = %d 有符号类型左移(正数)\n", i);printf("sizeof(int ) = %d\n", sizeof(int));int fi = -8;fi = fi << 3;printf("fi = %d 有符号类型左移(负数)\n", fi);return 0;
}
结果显示:
ui = 64 无符号类型左移(正数)
sizeof(unsigned int ) = 4
i = 64 有符号类型左移(正数)
sizeof(int ) = 4
fi = -64 有符号类型左移(负数)
分析:
移位对象 | 移位对象的二进制表示 (4字节 32位) | 所移的二进制位数 | 移位后的二进制 | 移位后的10进制 | 移位对象类型 | 移动方向 | 移位方式 |
---|---|---|---|---|---|---|---|
8 | 0…0 0000 1000 | 3 | 0…0 0010 0000 | 64 | unsigned int | 左移 | 逻辑左移 |
8 | 0…0 0000 1000 | 3 | 0…0 0010 0000 | 64 | int | 左移 | 逻辑左移 |
-8 | 1…1 1111 1000 | 3 | 1…1 1100 0000 | -64 | int | 左移 |
逻辑左移 |
结论:不管是否有无符号类型,也不管值的正负,均采用的是逻辑左移。
右移
1、当向右边移动3位,采用的什么方式的移动???
#include <stdio.h>
int main()
{unsigned int ui = 8;ui = ui >> 3;printf("ui = %d 无符号类型右移(正数)\n", ui);printf("sizeof(unsigned int ) = %d\n", sizeof(unsigned int));int i = 8;i = i >> 3;printf("i = %d 有符号类型右移(正数)\n", i);printf("sizeof(int ) = %d\n", sizeof(int));int fi = -8;fi = fi >> 3;printf("fi = %d 有符号类型右移(负数)\n", fi);return 0;
}
结果显示:
ui = 1 无符号类型右移(正数)
sizeof(unsigned int ) = 4
i = 1 有符号类型右移(正数)
sizeof(int ) = 4
fi = -1 有符号类型右移(负数)
分析:
移位对象 | 移位对象的二进制表示 (4字节 32位) | 所移的二进制位数 | 移位后的二进制 | 移位后的10进制 | 移位对象类型 | 移动方向 | 移位方式 |
---|---|---|---|---|---|---|---|
8 | 0…0 0000 1000 | 3 | 0…0 0000 0001 | 1 | unsigned int | 右移 | 逻辑右移 |
8 | 0…0 0000 1000 | 3 | 0…0 0000 0001 | 1 | int | 右移 | 算术右移 |
-8 | 1…1 1111 1000 | 3 | 1…1 1111 1111 | -1 | int | 右移 |
算术右移 |
结论:说明只要是有符号数,不管值是正还是负,右移时采用的都是算术右移。
再加一个实例:
(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。
总结:左移时总是移位和补零。右移时无符号数是移位和补零,此时称为逻辑右移;而有符号数大多数情况下是移位和补最左边的位(也就是补最高有效位),移几位就补几位,此时称为算术右移。
综上所述:
左移时总是移位和补零,无论是有符号类型数据还是无符号类型数据都统称为逻辑左移。
右移时无符号数是移位和补零,此时称为逻辑右移;
右移时而有符号数大多数情况下是移位和补最左边的位(也就是补最高有效位),移几位就补几位,此时称为算术右移。
参考连接:
1、https://blog.csdn.net/jiangjieqazwsx/article/details/79942154
2、https://blog.csdn.net/u013162035/article/details/78620803
3、https://blog.csdn.net/u012745229/article/details/51405332
4、https://www.baidu.com/link?url=gJVDtsgyNg83SN6nnAm5IAYLo-l9zh7T8UpVtVsngbRbqJw2GD3hYrv6OwES54FEZCDnlOhTP4z0Z6HmoOzSjX2fz8hxf9D5qYuFWibM_r_V3k39HksK5mpnFWHvosSt8EvtW9Gui5AEz-m0as7fFK&wd=&eqid=fa49686500000f6f000000025c2c6923
计算机原理与基础 —— C语言中的左移与右移相关推荐
- c语言中左移一位 由什么补充,计算机原理与基础 —— C语言中的左移与右移
1.双目运算符 位移位运算符是将数据看成二进制数,对其进行向左或向右移动若干位的运算. 位移位运算符分为左移和右移两种,均为双目运算符. 例如: 8 >> 3 (意思是8向右移动3 ...
- c语言的左移运算,C语言中的左移和右移运算.docx
C 语言中的左移和右移运算 C 语言中的左移和右移运算 (>> 和 < 1.各种数据格式(整型int ,字符型 char 等)占有几个存储单元(不同的编译器有所不同) 在TC2.0和 ...
- 关于C语言中的左移与右移
总结 ** 1. 左移时总是移位和补零,无论是有符号类型数据还是无符号类型数据都统称为逻辑左移. 2. 右移时无符号数是移位和补零,此时称为逻辑右移; 3. 右移时而有符号数大多数情况下是移位和补最左 ...
- C语言中的左移与右移[转]
先说左移,左移就是把一个数的所有位都向左移动若干位,在C中用<<运算符.例如: int i = 1; i = i << 2; //把i里的值左移2位 也就是说,1的2进制是00 ...
- C语言中的左移与右移
原文地址http://www.cnblogs.com/myblesh/articles/2431806.html 先说左移,左移就是把一个数的所有位都向左移动若干位,在C中用<<运算符.例 ...
- 计算机虚拟仿真专业,虚拟仿真技术在计算机专业网络基础课程教学中的应用
虚拟仿真技术在计算机专业网络基础课程教学中的应用 [摘要]本文以新疆石河子职业技术学院计算机专业网络基础课程的教学改革为切入点,以怎样改革现有的网络基础课程教学.以提升学生的学习与应用能力为根本目标, ...
- 单片机c语言左移的作用,[转载]单片机c语言中的左移右移
单片机c语言中的左移右移 左移 变量1 << 变量2 将变量1的二进制位值向左移动由变量2所指定的位数. 例如: a = 0x8f; // 10001111 a << 2; / ...
- DevOps中的左移和右移
一段时间以来,随着DevSecOps.DevTestOps的出现,表明DevOps软件开发方法已完全成熟并进化到了新的阶段,但究其根本,仍是通过频繁发布小型构建来加快产品的生产速度和上线速度.作为渐进 ...
- c语言负数左移右移_C语言里的左移和右移运算
C语言里的左移和右移运算 先说左移,左移就是把一个数的所有位都向左移动若干位,在C中用运算符.例如:int i = 1;i = i 2; /把i里的值左移2位也就是说,1的2进制是000.0001(这 ...
最新文章
- 如何通过HTTP优雅调用第三方-Feign
- 线扫相机——机器视觉中无限制物体的检测
- 让PHP更快的提供文件下载
- nginx负载均衡集群
- Dapper.NET——轻量ORM
- 3.3 1!到n!的和
- weblogic domain的安装与配置
- php关联微信支付宝,php实现微信和支付宝支付
- 根据mac地址获取生产厂商
- 自动升级系统的设计与实现(源码)
- Win11怎么设置人离开后电脑自动锁屏?
- python matplotlib pColor 网格线 消除
- Focal Loss 安装与使用 TensorFlow2.x版本
- 使用navicat将mysql数据转换为postgresql
- 带你领略3D转换的魅力~
- EventBus使用详解的
- (人工智障小白之路)keras 使用报错1
- 怎么主动发起话题_如何女生发起聊天话题?
- 英语语法---比较级和最高级的用法
- Pycharm上传工程到远程服务器
热门文章
- 帝国CMS7.5-后台的新闻正文编辑器更换成百度编辑器
- ceph.log 模块
- SSM框架的仓库管理系统
- 无人值守安装linux,无人值守安装Linux(PXE)
- 3G? 2G? 2.5G? 4G? 与 WIFI, GPRS,CDMA 3G无线上网
- 惠普在中国投放大面积广告 企图掩盖其质量问题新闻
- java 拦截器顺序_Springmvc拦截器执行顺序及各方法作用详解
- Redis不是一直号称单线程效率也很高吗,为什么又采用多线程了?
- 美团点评开源 SQL 优化工具 SQLAdvisor 测试报告
- NSSCTF PWN (入门)