返回信息流程序一:
unsigned char a=0x78;
unsigned char b=(a<<2)>>3;
printf("b=%d",b);
程序二:
unsigned char a=0x78;
unsigned char b=a<<2;
b=b>>3;
printf("b=%d",b);
为什么程序一和程序二的结果不同呢?
这是一条镜像帖。来源:北邮人论坛 / cpp / #37827同步于 2010/4/12
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖
关于移位的问题,求高手解答
mysterious03
2010/4/12镜像同步16 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
这个要看你的编译器选项,用通俗的说法就是:这两个程序的二进制代码不一样
【 在 mysterious03 (轻林) 的大作中提到: 】
: 程序一:
: unsigned char a=0x78;
: unsigned char b=(a<<2)>>3;
: ...................
真的结果不一样吗?不应该呀。。。你用的是什么编译器?
很奇怪厄。。。
原因有可能是这样的
;-------------------------------------------
0x78 01111000b
shl 2 -> 11100000b
shr 3 -> 00011100b 输出为0x1c
均为逻辑移位,即为程序一
;------------------------------------------
0x78 01111000b
shl 2 -> 11100000b
sar 3 -> 11111100b 输出为0xfc
第二次移位是算术移位,即为程序二
第二次把那个b=b>>3给单独写了,编译器给翻译成算术移位了,我猜
;------------------------------------------
输出是不是这样的?还有你的编译器是什么?
【 在 mysterious03 的大作中提到: 】
: 程序一:
: unsigned char a=0x78;
: unsigned char b=(a<<2)>>3;
: ...................
这个有点意思。
他们的唯一区别是(a<<2)>>3中的 a << 2 被当作32位处理了 注意类型提升
【 在 times123 的大作中提到: 】
: 楼主用的什么编译器呀?。。。
: 我能想到的就是算术移位和逻辑移位的区别了。。。不过已经声明了b为无符号的了么,啥编译器能给弄错了?
不是弄错 是类型提升了
应该没有类型提升吧?
没出现任何和类型提升的语句呀。。。
【 在 jmpesp 的大作中提到: 】
: 这个有点意思。
: 他们的唯一区别是(a<<2)>>3中的 a << 2 被当作32位处理了 注意类型提升
【 在 times123 的大作中提到: 】
: 应该没有类型提升吧?
: 没出现任何和类型提升的语句呀。。。
无符号char 被提升到 无符号int 刚好到32位 不过这个应该是跟编译器相关的
我猜想
数据在机器的表示都是以位模式存在的,在机器中,有符号和无符合都是位模式的,有符号和无符号的概念只是写程序时有,机器级就没有这个概念了,都以位模式存在。
而某编译器是默认算术移位的。。。
而程序一和程序二的结果不同,就是因为算术移位和逻辑移位?。。。
【 在 times123 的大作中提到: 】
: 我猜想
: 数据在机器的表示都是以位模式存在的,在机器中,有符号和无符合都是位模式的,有符号和无符号的概念只是写程序时有,机器级就没有这个概念了,都以位模式存在。
: 而某编译器是默认算术移位的。。。
: ...................
no
是因为前一个被当作32位处理,所以信息保留住
但是后一个被当作unsigned char处理,于是高位的信息被截断
于是 两者出现不同
还有,用算术移位还是逻辑移位是很容易辨别的 因为编译器可以根据类型信息,即是否是有符号数来生成正确的移位指令,所以这个是不会错的