免费注册 查看新帖 |

Chinaunix

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

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

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

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

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

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

yuxh正确。

printf内部是根据%d, %c等识别变量。虽然PUSH的是int, 但%c对应的程序就可以仅仅要最低BYTE,所以不会出问题。

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

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

printf不区分传入参数的类型,数据类型由格式符指定
%d的格式把数据转化为int型,而不管原来的数据类型是什么。
printf("sizeof(us) = %d %d\n", sizeof(us), (unsigned short)(us << 16));
us<<16得到32位数据11111111111111110000000000000000
转化为(unsigned short)后,高位截去就变成了0
若printf("sizeof(us) = %d %d\n", sizeof(us), (unsigned long)(us << 16)); 就会打印-65536
可以看一下:
  1. #include <stdio.h>;
  2. short us;
  3. main()
  4. {
  5.     us = 0xffff;
  6.     us <<= 8;
  7.     printf("sizeof(us) = %d %d\n", sizeof(us), us);
  8.     printf("sizeof(us) = %d %d\n", sizeof(us), (unsignec short)us);
  9. }
复制代码

结果就会不同。

论坛徽章:
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

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

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

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

确实如此!长见识了

论坛徽章:
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。

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

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

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

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

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

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

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

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP