打印

百思不得其解KEIL的ulong类型数据处理结果

[复制链接]
5009|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
sfesdm|  楼主 | 2012-2-11 23:56 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
沙发
Cortex-M0| | 2012-2-12 04:15 | 只看该作者
这不是问题,原因:

程序优化,最后结果可能未存储至count中,因为后续程序继续使用count中的计算结果,直接引用了。

使用特权

评论回复
板凳
hi21ic| | 2012-2-12 09:46 | 只看该作者
楼上说的不对。
可以做个单步调试来看结果。问题出在了keil的乘法上面。
(ulong) (RXD_BUF[1]*100000): 这一句的结果肯定大于0xFFFF,keil调用的是?C?LMUL,long型。
RXD_BUF[2]*10000 这一句:结果可能小于0xFFFF(65535),keil调用的是?C?IMUL,int型;

第二句改为:
count += (ulong) (RXD_BUF[2]*(ulong)10000);
显示让keil编译时调用long型乘法就好了。注意,ulong和long的函数不一样,一个是C?LIMUL,另一个是C?LMUL。

另外,对于这些大数乘法的时候,最好都标示清楚。后面可以加L,UL。

使用特权

评论回复
地板
ghpzhu| | 2012-2-12 13:08 | 只看该作者
count = (ulong)(RX_BUF[1]*100000)改成count = (ulong)RX_BUF[1]*100000就行了。
以此类推。

使用特权

评论回复
5
Ryanhsiung| | 2012-2-12 14:26 | 只看该作者
count = (ulong)(RX_BUF[1]*100000)改成count = (ulong)RX_BUF[1]*100000就行了。
以此类推。
ghpzhu 发表于 2012-2-12 13:08

类型转换的问题!!
(ulong)(RX_BUF[1]*100000)
  做的第一步:(RX_BUF[1]*100000)  会被转换成这里面最高级的长度,可能溢出!
  第二步:将第一步溢出结果,转换成ULONG
  第三步:你就看到了出错的结果

使用特权

评论回复
6
李富贵| | 2012-2-12 14:32 | 只看该作者
如果是Keil for ARM,那么看不出问题来,如果Keil for 51,那么100000这个明显溢出了。
C语言里面常数默认是int类型,而C51的int是16位的,100000必然被截掉,必须写成100000UL。

使用特权

评论回复
7
Cortex-M0| | 2012-2-12 15:41 | 只看该作者
楼上说的不对。
可以做个单步调试来看结果。问题出在了keil的乘法上面。
(ulong) (RXD_BUF[1]*100000): 这一句的结果肯定大于0xFFFF,keil调用的是?C?LMUL,long型。
RXD_BUF[2]*10000 这一句:结果可能小于0xFFFF( ...
hi21ic 发表于 2012-2-12 09:46


LZ要用count变量计算十进制结果999999,很明显,count变量是ulong类型。

倒是 6楼李富贵 说的有理,如果Keil for 51,那么100000这个明显溢出了。
C语言里面常数默认是int类型,而C51的int是16位的,100000必然被截掉,必须写成100000UL。

使用特权

评论回复
8
hi21ic| | 2012-2-12 19:45 | 只看该作者
LS的各位再仔细看看。
100000怎么溢出呢?编译器会去处理成long的。可以做一下验证,(ulong) (RXD_BUF[1]*100000)这一句没有错,没有溢出。
问题出现在:RXD_BUF[2]*10000
这一个实际调用的函数是INT的乘法。

使用特权

评论回复
9
sfesdm|  楼主 | 2012-2-12 22:38 | 只看该作者
谢谢各位的热心解答,3楼朋友已经说出原因了,我当时也考虑过是溢出的问题,于是就在前面加了ulong进行了强制转换,只不过还不曾想到前面加和后面加还是有区别的,看来还有很多细节要学习的。

使用特权

评论回复
10
ayb_ice| | 2012-2-13 08:31 | 只看该作者
...
10000L
100L
...
加L

使用特权

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

本版积分规则

49

主题

346

帖子

3

粉丝