近期有个朋友在程序中使用了对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. 限制TextBox输入,只能输入Double类型数字

    public class TextBoxDouble : TextBox { public TextBoxDouble() { KeyDown += TextBoxDouble_KeyDown; Te ...

  2. 第一章 andriod studio 安装与环境搭建

    原文 http://blog.csdn.net/zhanghefu/article/details/9286123 第一章   andriod studio 安装与环境搭建 一.Android Stu ...

  3. perl 公交车查询

    <pre name="code" class="cpp">decode_json 必须是unicode形式的字符,Dump不支持显示unicode形 ...

  4. 实用chrome插件

    2015年最实用的9款chrome插件 随着14年chrome浏览器的市场超过IE浏览器,chrome凭借它强劲性能和出色的使用体验真正的登上了平民级的殿堂.今天小编就为大家推荐9款自己常用的chro ...

  5. oracle的常见问题与解决

    刚接触oracle,在学习过程中遇到了很多的问题,本文章将会收藏我遇到的问题及如何解决. 错误一:ORA-28009:connection as sys should be as sysdba解决方法 ...

  6. 二叉查找树的Find,FindMin,FindMax的递归和非递归实现

    typedef struct TreeNode *Position; typedef struct TreeNode *SearchTree; struct TreeNode{ ElementType ...

  7. C# DataTable转实体 通用方法【转】

    public static T GetEntity<T>(DataTable table) where T : new()    {        T entity = new T();  ...

  8. XML转化DS等

    public class XmlData    {        /// <summary>        /// 将DataTable对象转换成XML字符串        /// < ...

  9. java代码如何快速添加作者描述的注释最好能有详细的图解

    MyEclipse 中自动插入作者.注释日期等de快捷键方法依次打开然后找到 Window -->Preferences->Java->Editor->Templates,在这 ...

  10. U3D学习使用笔记(一)

    1.在使用NGUI控件时出现两种回调函数,一种是直接给回调函数赋值,一种是使用EventDelegate. UISlider.onDragFinished = functionName; EventD ...