打印

移位操作

[复制链接]
4391|20
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
醉心369|  楼主 | 2013-3-13 12:28 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 醉心369 于 2013-5-3 09:16 编辑

unsigned char date[4];
unsigned long int value;
如果移位操作是:
value=date[0]<<24  | date[1]<<16  | date[2]<< 8 | date[3];
输出的结果value值是不对的,高16位输出为0,低6位是对的。

如果移位操作:
value=date[0]<<8  | date[1];
value=value<<16  | date[2]<< 8 | date[3];
输出的结果value值是正确的。

这是为什么啊

相关帖子

沙发
delin17| | 2013-3-13 12:49 | 只看该作者
本帖最后由 delin17 于 2013-3-13 12:50 编辑

这个问题,你看一上反汇编就知道了。
value=date[0]<<24  | date[1]<<16  | date[2]<< 8 | date[3];
等式都是8位数据进行操作,所以系统保存的结果是8位的。
所以经常在不是同类型的变量操作时要小心,数据运算的时候会将数据都转换成默认类型再进行运算。

第一个等式不会转换,因些错了,第二个运算前会去转换。

还有一点建议,你这个程序移位打上括号,不然可读性不好。

使用特权

评论回复
板凳
rockzone| | 2013-3-13 13:05 | 只看该作者
将其强制类型转换
(unsigned long)data

使用特权

评论回复
地板
醉心369|  楼主 | 2013-3-13 13:07 | 只看该作者
delin17 发表于 2013-3-13 12:49
这个问题,你看一上反汇编就知道了。
value=date[0]

反汇编只有用R6和R7 来保存date[2]和date[3],根本就没有date[0]和date[1]的事,这是咋回事,为什么系统保存的结果是8位的。

使用特权

评论回复
5
delin17| | 2013-3-13 13:25 | 只看该作者
date[0],data[1]
直接优化掉了,无效操作

使用特权

评论回复
6
ayb_ice| | 2013-3-13 13:27 | 只看该作者
数据溢出了

使用特权

评论回复
7
IC采购哪里去| | 2013-3-13 14:24 | 只看该作者

u=2067122411,1534765640&fm=0&gp=0.jpg (4.44 KB )

u=2067122411,1534765640&fm=0&gp=0.jpg

使用特权

评论回复
8
醉心369|  楼主 | 2013-3-13 14:42 | 只看该作者
delin17 发表于 2013-3-13 12:49
这个问题,你看一上反汇编就知道了。
value=date[0]

第一个等式不会转换,因些错了,第二个运算前会去转换。
这句话不太明白什么意思

使用特权

评论回复
9
醉心369|  楼主 | 2013-3-13 15:29 | 只看该作者
ccxlslr 发表于 2013-3-13 15:04
对于位数小于int类型的,默认按int型操作,因此不做类型转换,移位大于15就没意义了。你的操作数是一个8位 ...

对于位数小于int类型的,默认按int型操作,这是仅对于移位操作来说的吗?

使用特权

评论回复
10
飞鹰嵌入式| | 2013-3-13 17:11 | 只看该作者
2楼正解

使用特权

评论回复
11
delin17| | 2013-3-13 20:49 | 只看该作者
ccxlslr 发表于 2013-3-13 15:16
你也要注意,标准C都有整数提升。8位并不一定按8位运算

不是标准C有扩展,在嵌入式的世界,很多操作会根据实际情况去优化。8bit+8bit一定是两个8bit相加的。
实际这些操作都是根编译器有关系的。

使用特权

评论回复
12
delin17| | 2013-3-13 20:51 | 只看该作者
醉心369 发表于 2013-3-13 14:42
第一个等式不会转换,因些错了,第二个运算前会去转换。
这句话不太明白什么意思 ...

第一个等式的右值全是8bit的,所以他操作用的全是8bit的
而第二个等式的右值存在非8bit的,所以运算的时候会去转换。

使用特权

评论回复
13
jlass| | 2013-3-14 08:54 | 只看该作者
unsigned char date[4];
改成
unsigned int date[4];
应该就都可以了吧

使用特权

评论回复
14
ruiwei0201| | 2013-3-14 09:33 | 只看该作者
9楼正解

使用特权

评论回复
15
delin17| | 2013-3-14 10:04 | 只看该作者
我以VC,Keil MDK上试了,确实如你所说。
看来是我的理解有问题。

使用特权

评论回复
16
醉心369|  楼主 | 2013-3-14 18:45 | 只看该作者
delin17 发表于 2013-3-14 10:04
我以VC,Keil MDK上试了,确实如你所说。
看来是我的理解有问题。

看到这里有点晕,到底怎样理解呢

使用特权

评论回复
17
delin17| | 2013-3-15 17:38 | 只看该作者
标准的C是按ccxlslr所说的,Keil钩上那个选项之后也是。如果没有选中那个选项,基本上按我所说的执行的。

使用特权

评论回复
18
醉心369|  楼主 | 2013-3-15 18:20 | 只看该作者
delin17 发表于 2013-3-15 17:38
标准的C是按ccxlslr所说的,Keil钩上那个选项之后也是。如果没有选中那个选项,基本上按我所说的执行的。 ...

你哪里理解的有问题,正确的理解是什么

使用特权

评论回复
19
醉心369|  楼主 | 2013-3-23 18:04 | 只看该作者

使用特权

评论回复
20
efen| | 2013-3-23 22:57 | 只看该作者
"对于位数小于int类型的,默认按int型操作,因此不做类型转换,移位大于15就没意义了"

学习了,原来是这样。
难怪此前用一个uint变量位移16以上不能得到正确结果。还以为是单片机不支持。
话说ccxlslr楼去哪了。

使用特权

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

本版积分规则

60

主题

283

帖子

2

粉丝