关于移位的有意思的小问题

首先,直接上题目:

根据X得到F和G,其中X、F、G均是有符号的32位整型数,其中F = X/2; G = X>>1; 发现 F != G,下面的说法哪个是正确的:

A  编译错误   B  X是奇数  C X是负数  D F-G=1

上述4个选项中,首先排除A和B,显然随便举个反例就有了。

对于C,这里就涉及到负数在计算机中的表示形式了,至于怎么个表示法,下面一一道来:

对于负数,在计算机内的表示方法是怎么样的呢?

下面的代码可以说明一切:

void print(int x)
{
    //这里将形参的int转化为unsigned int,是为了说明负数的补码表示方法而已。
    unsigned int tmp = x;
    cout << tmp << endl;
    string s;
    while(tmp)
    {
        if(tmp & 1)  s.push_back('1');
        else s.push_back('0');
        tmp >>=1;
    }
    reverse(s.begin(),s.end());
    cout << s << endl;
}

上述代码的执行结果, x = 9 时,执行结果为:

1111 1111 1111 1111 1111 1111 1111 0111

这里的补码的表示其实很简单,转化过程无非是原码,反码和补码的顺序而已:

原码: 1 000 0000 0000 0000 0000 0000 0000 1001 //最高位是符号位,后面的31位是数字位

反码: 1 111 1111 1111 1111 1111 1111 1111 0110 //除了符号位,其他为全部变反

补码: 1 111 1111 1111 1111 1111 1111 1111 0111 //反码加1即可

这样的话,对于上述的代码的结果解析就这样了,现在执行 :

F = X/2 = -9/2 = -4 ; // 这就是除法运算

G = X>>1 = (-9) >> 1 就是将上述的补码部分向右移一位,执行过称为:

  1   111 1111 1111 1111 1111 1111 1111 0111

  1 1 111 1111 1111 1111 1111 1111 1111 011
1  //去掉最右边的蓝色的1,加上最左边的绿色的1

于是乎,上述结果变为:

  1 1 111
1111 1111 1111 1111 1111 1111 011  //这里是结果的补码,现在讲结果的补码转换为源码,从而得到原来的数值。其过程为:

  1 111 1111 1111 1111 1111 1111 1111
1011  //补码

  1 111
1111 1111 1111 1111 1111 1111 1010 //补码减去1 变为反码

  1
000 0000 0000 0000 0000 0000 0000 0101  //除了最高位的符号位,其他为变反,

结果竟然是-5!!!!
也就是说 (-9 >> 1) = -5 !!!!

也就是说出现了上述的 F != G, F-G = 1 。于是答案是D.

时间: 2024-10-03 07:11:06

关于移位的有意思的小问题的相关文章

CSAPP中一个有意思的小东西

回家的效率明显下降了,但是第三章还是快要结束的节奏.今天看到定长数组这里的时候,看到一个好玩的东西.在计算机的底层中,所有对数组的操作都是利用指针来完成的.数组其实也是一个很简单的数据结构,就是把一些最简单的数据类型合并在一段连续的内存区域上,这就是一个复合类型---数组. 学C语言的时候,大家都知道访问数组元素有两种方法,一种是利用数组名加索引的形式,另外一种就是利用指针加上偏移量的形式.在底层中,不管你用什么方式来访问元素,最后多会转化成对指针的操作. 在编写 代码的时候,编译器在编译过程中

【小游戏】有意思的小游戏集合

平常喜欢玩一些小游戏,有些游戏真的很有创意啊,以下是推荐列表 小萌球穿越记(BLYM) http://www.u148.net/game2/2014/4/Blym/ 的确很萌啊,小萌球钻进蓝色砖块的设计你很有意思,有些关卡还有点挑战. 37关,要先把三块相连的砖当中的左右两块分别移开,然后用中间一块下去拉闸.然后上去拉左边的闸,但是去左边之前要预留空间,要不然跳不回来.再去右边的话要先利用砖块掉到下面去,然后吹上来. 38关,移三个和移两个的道理是一样的.拉闸被最右边那块砖挡住了. 史上最贱的游

一些有意思的小知识(持续更新?)

php 有意思的小题

/** * 你的是一个数字和一个字符串进行比较,PHP会把字符串转换成数字再进行比较.* PHP转换的规则的是:若字符串以数字开头,则取开头数字作为转换结果,若无则输出0.***/1)$a ="abc";if($a==0){echo "等于0";}else{echo "不等于0";} //输出结果是0; 2)$num1 = '1';$num2 = 'a1';echo $num1 + $num2; //结果输出1; //这里,数字与字符相加,PHP

有意思的小程序

        //函数一         var a = 'a1';         function f1(){             var a = a || 'a2';             alert(a);         }         f1();                  // 函数二         var b = 'b1';         function f2(){             b = b || 'b2';             alert(

有意思的小习题

1.需求,编写函数,输入两个时间,格式为1970-1-1 12:00:00,1970-1-1 14:30:00,计算两个时间差,要求输出"2小时30分" import timedef func(start,end): struct_start=time.strptime(start,"%Y-%m-%d %H:%M:%S") struct_end=time.strptime(end,"%Y-%m-%d %H:%M:%S") stump_start=

【算法】 小知识

记录一些在我看来有意思的小算法知识 ■ 识别有效的括号字符串 以小括号为例,在带括号的字符串中,如果只提取出括号作为特征,"()",""(空串),"(()(()(())))"这些是有效的括号字符串,虽然有嵌套但是没有乱套,每个左括号都可以找到正确的右括号配对 而")(())","(((","("等这些字符串就是非法的 有效的括号字符串的要求应该有1.左括号和右括号数量应该相等 2. 不能

第一个小程序云笔记通过微信审核分享

今天快要下班了,都准备收拾电脑下班,突然微信推送了个消息:小程序通过微信审核了,按耐不住心中的喜悦,主动加班给大家分享这次通过审核的一些总结. 审核通过后,处于审核通过,待发布状态 小程序介绍 我们做的这个小程序是热点云笔记,是一个很简单的记事本,主要是通过微信登录,让用户免输入账号云端同步文本. 说了这么多,还不如截个图,所谓一图顶万言. 虽然审核通过了,但是还是有些总结的 (1)微信是否允许小程序的风格和微信的绿色风格出入很大? 从这个审核通过的分享来看,是没问题,我们是红色,和微信的整体风

团队项目遇到的一些小问题

我们选择了电梯调度问题,在分析客户需求时,我们在一些问题上讨论比较激烈,没有得到说服所有人的答案,记录下来以便日后分析. 四部电梯在每一层只有一组“上”“下”按钮,这是一切问题的基础,我们能否知道每一个乘客欲去往的楼层?我们是否要给出顾客乘坐哪台电梯的建议?或者是,在电梯到达本层后,乘客根据自己的经验选择是否乘坐? 如果我们并不能知道每一个顾客的需求,想给乘客最满意的体验,我们需要尽可能调度那部可以通往全部楼层的电梯,让其余三部闲置完全闲置,显然这是不可能的.但在我们不了解每个顾客的需求时,贸然