近期有个朋友在程序中使用了对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. jquery.post方法回调函数

    1 function(data){} 此post请求成功后调用之,data是请求成功后服务器返回的东西.如果在servlet中有response.getWriter().println("s ...

  2. css 问题总结

    background: <color> <image> <position> <attachment> <repeat>本文来自:佳木中国( ...

  3. Flex中如何通过horizontalTickAligned和verticalTickAligned样式指定线图LineChart横竖方向轴心标记的例子

    原文http://blog.minidx.com/2008/12/03/1669.html 接下来的例子演示了Flex中如何通过horizontalTickAligned和verticalTickAl ...

  4. 【转】Logistic regression (逻辑回归) 概述

    Logistic regression (逻辑回归)是当前业界比较常用的机器学习方法,用于估计某种事物的可能性.比如某用户购买某商品的可能性,某病人患有某种疾病的可能性,以及某广告被用户点击的可能性等 ...

  5. Struts2 使用通配符动态请求Action

    在以前的学习中,<action>元素的配置,都是用明确的配置,其name.class等属性都是一个明确的值.其实Struts2还支持class属性和method属性使用来自name属性的通 ...

  6. warning C4133: “函数”: 从“char [5]”到“LPCWSTR”的类型不兼容

    弹窗打开一个网页,但是报错,代码如下: #include <stdio.h> #include <windows.h> void main() { ShellExecute(, ...

  7. POJ 3318 - Matrix Multiplication 第一次用随机化解决问题...

    随机化还是很厉害的...印象最深的是以前手写快排~~一般加个随机化会使耗时不受输入数据的..时间更加稳定 这个题是人品题了...开始交了好多遍都过不了..多交几次终于过了... Program: #i ...

  8. vmlinux,vmlinuz,bzimage,zimage,initrd.img的区别与联系

    1.vmlinux vmlinux是未压缩的内核,vmlinux 是ELF文件,即编译出来的最原始的文件.用于kernel-debug,产生system.map符号表,不能用于直接加载,不可以作为启动 ...

  9. 【POJ 1125】Stockbroker Grapevine

    id=1125">[POJ 1125]Stockbroker Grapevine 最短路 只是这题数据非常水. . 主要想大牛们试试南阳OJ同题 链接例如以下: http://acm. ...

  10. Cannot access empty property

    致命错误:不能够进入此空值,位于E:\sunlion\web\down\class\db_sql.php 代码 <?php Class TestClass1{ var $class2; publ ...