免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3603 | 回复: 11
打印 上一主题 下一主题

一个二进制移位产生的疑难问题…… [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2004-09-23 10:25 |只看该作者 |倒序浏览
WORD src = 65535;
结果trace发现src << 16 = -65536,为什么会等于这么多?-65536用二进制表示应该是多少呢?
我怎么感觉src是16位的,左移16位后,应该为0?

另外计算机中表示负数是用补码还是反码表示的?

论坛徽章:
0
2 [报告]
发表于 2004-09-23 10:45 |只看该作者

一个二进制移位产生的疑难问题……

>;>;另外计算机中表示负数是用补码还是反码表示的?
一般而言,据我所知,都是补码表示的

另外,WORD是什么类型的?

论坛徽章:
0
3 [报告]
发表于 2004-09-23 11:24 |只看该作者

一个二进制移位产生的疑难问题……

我刚看了一篇文章,里面说所有原码、反码、补码的转换都是在计算机的最底层进行的,而在我们使用的汇编、C等其他高级语言中使用的都是原码。
---------------------------------------------------------------------
可是我就更不懂了
WORD 是VC里面定义的unsigned short,就是最高位也是数字位,不是符号位。
那为何65535 << 16也就是1111111111111111左移16位后,得到的值确实-65536,也就是说其一无符号位移位运算后,产生的值是有符号位;
其二,-65536是一个什么数?因为16位的二进制数,如果是有符号位的,无论是原码还是补码,这个数都已经超过范围。
唯一只有一种可能,就是16位的数,左移16位,值实际已经扩展到32位,扩展到32位111111111111111100000000000000000
扩展出来的数是什么码?如果是补码,取反+1的结果倒是和-65536的值相符。
那么也就是说,计算机中的数据用的还是补码?

论坛徽章:
0
4 [报告]
发表于 2004-09-23 13:23 |只看该作者

一个二进制移位产生的疑难问题……

>;>;汇编、C等其他高级语言中使用的都是原码。
还是那句话,据我所知是补码

我下去用gcc试了一下,printf用%d格式的话就是输出-65536,我能想到的解释就是%d格式输出的时候进行了扩展,原因就是你说的那样:有符号的扩展到了32位。

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
5 [报告]
发表于 2004-09-23 18:34 |只看该作者

一个二进制移位产生的疑难问题……

这里WORD应该是long型,4个字节
65535=00000000000000001111111111111111
左移16位得到
11111111111111110000000000000000
这是个负数,为-65536

论坛徽章:
0
6 [报告]
发表于 2004-09-24 09:47 |只看该作者

一个二进制移位产生的疑难问题……

WORD=unsigned short结果也是一样的,因为整数(char, short, int, long)进行四则运算或移位操作的中间结果用32bits寄存器保存。unsigned/signed的区别仅在右移操作时才能体现出来,而这里是左移。
对于函数调用(比如printf)的参数,是通过push指令,只能是32bits操作数,因此printf内部无法区分到底参数是何种类型(char,short,int,long),只能通过%d,知道是有符号int。

论坛徽章:
0
7 [报告]
发表于 2004-09-24 10:15 |只看该作者

一个二进制移位产生的疑难问题……

>;>;因为整数(char, short, int, long)进行四则运算或移位操作的中间结果用32bits寄存器保存。unsigned/signed的区别仅在右移操作时才能体现出来,而这里是左移。

确实如此!长见识了

论坛徽章:
0
8 [报告]
发表于 2004-09-24 10:15 |只看该作者

一个二进制移位产生的疑难问题……

这本来就没有任何问题。

#include <stdio.h>;
unsigned short us;
main()
{
    us = 0xffff;
    us <<= 16;
    printf("sizeof(us) = %d   %d\n", sizeof(us), us);
}

结果是0。
谁说printf不能区分char, short?

原帖由 "mfmain" 发表:
WORD=unsigned short结果也是一样的,因为整数(char, short, int, long)进行四则运算或移位操作的中间结果用32bits寄存器保存。unsigned/signed的区别仅在右移操作时才能体现出来,而这里是左移。
对于函数调用(比?.........

论坛徽章:
0
9 [报告]
发表于 2004-09-24 11:40 |只看该作者

一个二进制移位产生的疑难问题……

如果改为下面的就出现问题了:

  1. #include <stdio.h>;
  2. unsigned short us;
  3. main()
  4. {
  5. us = 0xffff;
  6. //us <<= 16;
  7. printf("sizeof(us) = %d %d\n", sizeof(us), us << 16);
  8. }

复制代码


之所以出问题应该是因为把us传进printf的时候用的是32位的寄存器吧?

论坛徽章:
0
10 [报告]
发表于 2004-09-24 11:56 |只看该作者

一个二进制移位产生的疑难问题……

出现问题了就对了。
printf("sizeof(us) = %d   %d\n", sizeof(us), (unsigned short)(us << 16));
就好了。

否则:

long1 = short2 + 2;
是把short2先类型转换成long, 再运算,结果给long1
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP