近期有个朋友在程序中使用了对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. EditPlus3.3 集成 SVN

    今天在玩EditPlus的时候,由于自己想上传文件至SVN,本机已经安装了TSVN,听说近期EditPlus支持了SVN操作,于是自己便带着好奇的心试试了.     已有的环境: EditPlus 3 ...

  2. Android APN配置

    APN概念 APN(Access Point Name),即“接入点名称”,用来标识GPRS的业务种类,目前分为两大类:CMWAP(通过GPRS访问WAP业务).CMNET(除了WAP以外的服务目前都 ...

  3. POJ 3484 Showstopper(二分答案)

    [题目链接] http://poj.org/problem?id=3484 [题目大意] 给出n个等差数列的首项末项和公差.求在数列中出现奇数次的数.题目保证至多只有一个数符合要求. [题解] 因为只 ...

  4. Entity Framework学习笔记

    原文地址:http://www.cnblogs.com/frankofgdc/p/3600090.html Entity Framework学习笔记——错误汇总   之前的小项目做完了,到了总结经验和 ...

  5. Cube(规律)

    Cube Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  6. TCPDUMP详解(续)

    TCPdump抓包命令  tcpdump是一个用于截取网络分组,并输出分组内容的工具.tcpdump凭借强大的功能和灵活的截取策略,使其成为类UNIX系统下用于网络分析和问题排查的首选工具.  tcp ...

  7. 【转】使用Navicat for Oracle新建表空间、用户及权限赋予

    首先.我们来新建一个表空间.打开Navicat for Oracle,输入相关的的连接信息.如下图: 填入正确的信息,连接后.我们点击面板上的“其他”下的选项“表空间”,如下图: 进入表空间的界面,我 ...

  8. 【转】java jawin api 中文 invoke方法

    org.jawin Class FuncPtr java.lang.Object org.jawin.FuncPtr ----------------------------------------- ...

  9. SQLServer 中实现类似MySQL中的group_concat函数的功能

    SQLServer中没有MySQL中的group_concat函数,可以把分组的数据连接在一起. 后在网上查找,找到了可以实现此功能的方法,特此记录下. SELECT a, stuff((SELECT ...

  10. 提示constructor无法location的原因

    1.缺少对应属性的set方法 2.缺少确实没有对应的方法 3.对应的构造方法中参数类型不匹配 4.java对象不会在寻找构造函数时执行数据类型的强制类型转换,没有对应的类型就返回异常,不会自动强制转换 ...