近期有个朋友在程序中使用了对16进制数做负数移位(编译器是gcc),本人最次产生好奇。所以研究了一些。

对一个数做负数位移位的操作是不规范的,可是是可行的。

详细样例:
char tmp = 0x10;
tmp = tmp << -1;
大家猜猜结果是什么。有人猜是tmp左移-1位不就是右移1位吗?结果是0x01?
非常遗憾。电脑和人脑是不一样的。结果是0
为什么呢?为了找出原因,本人进行了一些小小的測试。并做出了有根据的结果。

因为知道+0和-0的差别,所以,我首先将tmp << -128(-128就是-0),和猜想的一样。结果是0x10
而-128的二进制是 1000 000b
继续,将tmp << -127。结果是0x20,左移了1位
-127的二进制是 1000 0001b
迫不及待,尝试 tmp << -126。结果是0x40,左移了2位
-126的二进制是 1000 0010b
这时,大家应该和我一样,看出了端倪,可是先不要说出来,先看看他们以相同的值向右移:
首先将tmp >> -128(-128就是-0),结果是0x10
而-128的二进制是 1000 000b
继续,将tmp >> -127,结果是0x08,右移了1位
-127的二进制是 1000 0001b
迫不及待。尝试 tmp >> -126。结果是0x04,右移了2位
-126的二进制是 1000 0010b

这时,大家能够大胆的的推測了,移位操作中若移动的是一个负数,那么移动的位数以这个负数的二进制形式的低七位决定。
若还有猜疑。继续測试:
tmp << -255 结果为0x20。-255的二进制为0x1 0000 0001b
tmp << -511 结果为0x20, -511的二进制为0x10 0000 0001b
tmp << -1023 结果为0x20,-1023的二进制为0x100 0000 0001b

如今大家能够肯定的说:移位操作中若移动的是一个负数。那么移动的位数以这个负数二进制形式的低七位决定。

如今的longlong型长度貌似最大也仅仅有到64位,若要达到128位。这个编译器就要改动了。)


在写完本文后,我在工作中不小心发现了不妥。以上的结果不过只代表了有符号char型的移位规则。所以,以上的结论须要进一步的进行拓展。
以下是拓展后的结论:
当一个数为有符号数时。设这个有符号数的二进制位数为k(比方int型在32位系统中,它的二进制位数为32),那么这个数向左或向右移动n位时,这个数仅仅移动这个n数的二进制形式下低k-1位所指代的那个正数位。
当一个数为无符号数时。设这个有符号数的二进制位数为k(比方int型在32位系统中,它的二进制位数为32),那么这个数向左或向右移动n位时,这个数仅仅移动这个n数的二进制形式下低k位所指代的那个正数位。

因为本人水平有限,如有错误,请指正。本人不胜感激。




关于c语言中负数位移位操作的漫谈的更多相关文章

  1. c语言中的位移位操作

    先要了解一下C语言里所有的位运算都是指二进制数的位运算.即使输入的是十进制的数,在内存中也是存储为二进制形式. “<<”用法: 格式是:a<<m,a和m必须是整型表达式,要求m ...

  2. C语言中负数的存储方式

    详细介绍负数的文章: https://blog.csdn.net/daiyutage/article/details/8575248 1.以char类型举例,其取值范围是 -128 ~ 127,即-2 ...

  3. 单片机的C语言中位操作用法2

    单片机的C语言中位操作用法 在对单处机进行编程的过程中,对位的操作是经常遇到的.C51对位的操控能力是非常强大 的.从这一点上,就可以看出C不光具有高级语言的灵活性,又有低级语言贴近硬件的特点. 这也 ...

  4. C语言中的正负数及其输出

    在数学中,数字有正负之分.在C语言中也是一样,short.int.long 都可以带上正负号,例如: //负数 ; short a2 = -0x2dc9; //十六进制 //正数 ; ; //八进制 ...

  5. c语言中的文件流

    一.打开和关闭文件 #include int main( void ) { FILE* pReadFile = fopen( "E:\\mytest.txt", "r&q ...

  6. c语言中的左移和右移

    先说左移,左移就是把一个数的所有位都向左移动若干位,在C中用<<运算符.例如: int i = 1;i = i << 2;  //把i里的值左移2位 也就是说,1的2进制是00 ...

  7. C语言中的按位移动及其简单引用

    C语言中的按位移动及其简单应用 在C语言中按位左移用”<<”表示,按位右移用”>>”表示. 按位左移和按位右移运算经常被用来替换乘二和除二运算,但是要注意,这两者之间并不完全等 ...

  8. C语言中的左移与右移 <<, >> 位运算

    这里参考了一篇很好的位运算,涉及到位运算可能会遇到的正负号问题,左右溢出怎么处理问题. 参考: 1. https://www.cnblogs.com/myblesh/articles/2431806. ...

  9. C语言中两位ASCII码可以表示汉字

    最近偶然有人问到这个相关字符编码的问题,所以百度了下参考了这两个资料,进行了简单分析. ******************************************************** ...

随机推荐

  1. SPI Flash

    使用了MX25L512的SPI接口的Flash 电路连接图: 总的大小512kb,即64kB,sector的大小为256 Bytes,block的大小为4k Bytes 调试时出现的问题: 1.Fla ...

  2. Java - 字符串和Unicode互转 - 解析小米pm.min.js

    小米JS地址: http://p.www.xiaomi.com/zt/20130313/huodong/pm.min.js 上面这个JS是小米抢手机页面的代码.和抢手机有直接关联.. 虽然我3次都没抢 ...

  3. 打造你的办公环境-email篇

    1. 配置安装 procmailr 和 getmail ///////////////////////////////// ignore the follow  /////////////////// ...

  4. (转)iOS 开发,工程中混合使用 ARC 和非ARC

    [前提知识] ARC:Automatic Reference Counting,自动引用计数 在开发 iOS 3 以及之前的版本的项目时我们要自己负责使用引用计数来管理内存,比如要手动 retain. ...

  5. uva 10306 - e-Coins(完全背包)

    题目链接:10306 - e-Coins 题目大意:给出m和s, 再给出m种电子硬币,每种硬币有两种金额xi,yi.现在要在m种硬币种选若干个硬币,可以重复选同一种硬币, 使得(x1 + x2 + . ...

  6. 使用SQL脚本删除冗余的视图和表

    使用SQL脚本删除冗余的视图和表 SQL脚本删除视图信息 USE DatabaseGOIF OBJECT_ID('ViewName')IS NOT NULLBEGINDROP VIEW ViewNam ...

  7. iOS8的新特性

    iOS8的几个重要变化: 家庭分享.用户可以创建家庭分享,除创建者之外最多可以加入6个家庭成员.通过该功能,用户可以和家人分享位置.照片.日历.应用程序.音乐和视频等. 键盘.苹果在iOS8之后开放了 ...

  8. eclipse中输入的中文为繁体的问题

    今天在eclipse中编写注释的时候发现,输入的中文都为繁体,且只在eclipse编辑器中为繁体,切换到网页中则为正常. 最后发现,竟然是输入法的shift+ctrl+F快捷键和eclipse的冲突. ...

  9. 制作与使用静态链接库(.lib)文件

    (一)制作.lib文件 (1)打开vs,选择“新建项目”,选择“Visual C++“,选择”Win32 控制台应用程序“. (2)点击”确定“,点击”下一步“,设置如下 (3)点击”完成“,然后就可 ...

  10. Devpexpress 打印预览问题

    devexpress 12 之前报表打印: XtraReports rp1 = new XtraReports(); rp1.ShowPreview(): 即可预览报表: devexpress 13 ...