打印

有符号数,逻辑左移和算术左移一定相同吗?

[复制链接]
12449|18
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
hwk612167|  楼主 | 2011-10-10 12:26 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 hwk612167 于 2011-10-10 15:15 编辑

#include<stdio.h>
int main(void)
{
    signed char c = 0xa1;
    short x = 0xa1a1;
    printf("%x===%d\n%x===%d\n%x===%d\n",c, c, (c<<1), (c<<1), (c>>1), (c>>1));
    printf("%x===%d\n%x===%d\n%x===%d\n",x, x, (x<<1), (x<<1), (x>>1), (x>>1));
    getch();
    return 0;
}
以上程序在win-tc运行结果为:
ffa1===-95   
ff42===-190 (问题1:按我理解结果应为0x42===66??哪里出问题了)
ffd0===-48  (问题2:以上3个结果怎么多了ff???)
a1a1===-24159
4342===17218(问题3:为何又变正数了?)
d0d0===-12080
----------------分割线------------------
教材上说算术左移和逻辑左移相同,不太明白,写了个程序测试下,更糊涂了,求各位指点下,谢谢!

相关帖子

沙发
yewuyi| | 2011-10-10 12:54 | 只看该作者
主要重点是进位标志是否参与了移位。

使用特权

评论回复
板凳
computer00| | 2011-10-10 13:03 | 只看该作者
C语言移位时会先扩展为int型的。
2楼,这个问题跟进位无关。

使用特权

评论回复
地板
yewuyi| | 2011-10-10 13:18 | 只看该作者
C语言移位时会先扩展为int型的。
2楼,这个问题跟进位无关。
computer00 发表于 2011-10-10 13:03


百度了一下,结果是:
逻辑左移=算数左移,右边统一添0
逻辑右移,左边统一添0
算数右移,左边添加的数和符号有关
e.g:1010101010,其中[]位是添加的数字
逻辑左移一位:010101010[0]
算数左移一位:010101010[0]
逻辑右移一位:[0]101010101
算数右移一位:[1]101010101
------------------------------------------------
那就是符号位移动位置的问题了,ASM中只有带不带进位的指令,这个只能先扩展数据长度才能保证了。

使用特权

评论回复
5
yewuyi| | 2011-10-10 13:20 | 只看该作者
好像很少管它,俺从来没关心它,直接都是变量左移或者右移。

使用特权

评论回复
6
hwk612167|  楼主 | 2011-10-10 13:47 | 只看该作者
注:win-tc int为16位。
继续等答案。。。

使用特权

评论回复
7
ayb_ice| | 2011-10-10 14:32 | 只看该作者
一般是这样的
至于有没有"变态"的就不知道了

使用特权

评论回复
8
hwk612167|  楼主 | 2011-10-10 15:16 | 只看该作者
问题3处结果是对的?负数算术左移成正数了。
7# ayb_ice

使用特权

评论回复
9
ayb_ice| | 2011-10-10 15:38 | 只看该作者
本帖最后由 ayb_ice 于 2011-10-10 15:40 编辑

FSL S08指令手册明确说明
"ASL (same as LSL)"

未命名.JPG (139.46 KB )

未命名.JPG

使用特权

评论回复
10
computer00| | 2011-10-10 21:09 | 只看该作者
signed char c = 0xa1;
c的最高位为1,所以它是一个负数,当它扩展为16位的int型时,前面当然要加上0xFF了,结果就成了0xffa1。
0xffa1左移一位,最高位扔掉,结果当然就是0xff42了,也就是-190。

0xa1a1,左移一位,扔掉最高位,就是0x4342,最高位为0,当然就是正数了。

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
highgear + 1
11
highgear| | 2011-10-10 21:45 | 只看该作者
这些都是一些最基本的算术问题。

必须清楚无符号,有符号整数之间的转换以及范围,同时注意移位操作可以分为算术移位与逻辑移位两个不同的操作。

使用特权

评论回复
12
highgear| | 2011-10-10 21:56 | 只看该作者
没注意到楼主的问题是 左 移。

有符号数的逻辑左移和算术左移是相同的,只是左移会把最高位移除。对于有符号数,最高位就是符号位,1 代表负整数(范围 8bit: [0x80, 0xFF]; 16bit: [0x8000, 0xFFFF]) ,0 代表正整数(范围 8bit: [0, 0x7F]; 16bit: [0, 0x7FFF])

使用特权

评论回复
13
hwk612167|  楼主 | 2011-10-11 09:04 | 只看该作者
:lol目前为止回帖的都是大牛级人物啊。
负数算术左移变成正数了,总觉得有些不妥。

使用特权

评论回复
14
ayb_ice| | 2011-10-11 09:09 | 只看该作者
:lol目前为止回帖的都是大牛级人物啊。
负数算术左移变成正数了,总觉得有些不妥。
hwk612167 发表于 2011-10-11 09:04

这个没有什么不妥的,需要软件处理
类似的问题很多
比如:
两个正数相加等于负数....

使用特权

评论回复
15
hwk612167|  楼主 | 2011-10-11 12:13 | 只看该作者
赶上论坛首页了,:P 结贴了

使用特权

评论回复
16
蓦然回首;| | 2014-5-27 22:21 | 只看该作者
11楼的highgear回答的很深刻,楼主的signed char c = 0xa1;而有符号char它的范围是-127至127。而0xa1换成十进制都等于161了,明显超出范围了,所以楼主本身初始化就有问题。

使用特权

评论回复
17
liujinxu212| | 2015-7-2 01:26 | 只看该作者
ayb_ice 发表于 2011-10-10 15:38
FSL S08指令手册明确说明
"ASL (same as LSL)"

这个给力

使用特权

评论回复
18
hgjinwei| | 2015-7-2 09:04 | 只看该作者
本帖最后由 hgjinwei 于 2015-7-2 09:12 编辑

这里涉及到了两个问题:
1、c,x均为带符号数,移位采用算术移位,即:
D, D<<1,D>>1
A1(10100001), 42(01000010),D0(11010000)
A1A1(1010000110100001), 4342(0100001101000010), D0D0(1101000011010000)

2、printf中,不定参采用int型对齐输入,%x,%d 采用int型提取参数,signed char型的c被强制转化为int型,即:
D, D<<1,D>>1
FFA1(1111111110100001), 0042(0000000001000010), FFD0(1111111111010000)
A1A1(1010000110100001), 4342(0100001101000010), D0D0(1101000011010000)

注:以上采用16位分析,int型为16位带符号整型。

使用特权

评论回复
19
lefeng| | 2015-7-3 21:49 | 只看该作者
两个左移是相同的,只是左移会把最高位移除

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:前进 前进 前进

20

主题

511

帖子

3

粉丝