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

[复制链接]
13263|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中只有带不带进位的指令,这个只能先扩展数据长度才能保证了。
yewuyi 发表于 2011-10-10 13:20 | 显示全部楼层
好像很少管它,俺从来没关心它,直接都是变量左移或者右移。
 楼主| hwk612167 发表于 2011-10-10 13:47 | 显示全部楼层
注:win-tc int为16位。
继续等答案。。。
ayb_ice 发表于 2011-10-10 14:32 | 显示全部楼层
一般是这样的
至于有没有"变态"的就不知道了
 楼主| hwk612167 发表于 2011-10-10 15:16 | 显示全部楼层
问题3处结果是对的?负数算术左移成正数了。
7# ayb_ice
ayb_ice 发表于 2011-10-10 15:38 | 显示全部楼层
本帖最后由 ayb_ice 于 2011-10-10 15:40 编辑

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

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
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

查看全部评分

highgear 发表于 2011-10-10 21:45 | 显示全部楼层
这些都是一些最基本的算术问题。

必须清楚无符号,有符号整数之间的转换以及范围,同时注意移位操作可以分为算术移位与逻辑移位两个不同的操作。
highgear 发表于 2011-10-10 21:56 | 显示全部楼层
没注意到楼主的问题是 左 移。

有符号数的逻辑左移和算术左移是相同的,只是左移会把最高位移除。对于有符号数,最高位就是符号位,1 代表负整数(范围 8bit: [0x80, 0xFF]; 16bit: [0x8000, 0xFFFF]) ,0 代表正整数(范围 8bit: [0, 0x7F]; 16bit: [0, 0x7FFF])
 楼主| hwk612167 发表于 2011-10-11 09:04 | 显示全部楼层
:lol目前为止回帖的都是大牛级人物啊。
负数算术左移变成正数了,总觉得有些不妥。
ayb_ice 发表于 2011-10-11 09:09 | 显示全部楼层
:lol目前为止回帖的都是大牛级人物啊。
负数算术左移变成正数了,总觉得有些不妥。
hwk612167 发表于 2011-10-11 09:04

这个没有什么不妥的,需要软件处理
类似的问题很多
比如:
两个正数相加等于负数....
 楼主| hwk612167 发表于 2011-10-11 12:13 | 显示全部楼层
赶上论坛首页了,:P 结贴了
蓦然回首; 发表于 2014-5-27 22:21 | 显示全部楼层
11楼的highgear回答的很深刻,楼主的signed char c = 0xa1;而有符号char它的范围是-127至127。而0xa1换成十进制都等于161了,明显超出范围了,所以楼主本身初始化就有问题。
liujinxu212 发表于 2015-7-2 01:26 | 显示全部楼层
ayb_ice 发表于 2011-10-10 15:38
FSL S08指令手册明确说明
"ASL (same as LSL)"

这个给力
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位带符号整型。
lefeng 发表于 2015-7-3 21:49 | 显示全部楼层
两个左移是相同的,只是左移会把最高位移除
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:前进 前进 前进

20

主题

511

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部