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

[复制链接]
5960|9
 楼主| sfesdm 发表于 2012-2-11 23:56 | 显示全部楼层 |阅读模式
程序如图1,其中RXD_BUF数组是uchar型的,仿真的结果如图2
其中count的十进制结果是934463,为什么不是预想中的999999呢?求解!不胜感激!!

本帖子中包含更多资源

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

×
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就行了。
以此类推。
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
  第三步:你就看到了出错的结果
李富贵 发表于 2012-2-12 14:32 | 显示全部楼层
如果是Keil for ARM,那么看不出问题来,如果Keil for 51,那么100000这个明显溢出了。
C语言里面常数默认是int类型,而C51的int是16位的,100000必然被截掉,必须写成100000UL。
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。
hi21ic 发表于 2012-2-12 19:45 | 显示全部楼层
LS的各位再仔细看看。
100000怎么溢出呢?编译器会去处理成long的。可以做一下验证,(ulong) (RXD_BUF[1]*100000)这一句没有错,没有溢出。
问题出现在:RXD_BUF[2]*10000
这一个实际调用的函数是INT的乘法。
 楼主| sfesdm 发表于 2012-2-12 22:38 | 显示全部楼层
谢谢各位的热心解答,3楼朋友已经说出原因了,我当时也考虑过是溢出的问题,于是就在前面加了ulong进行了强制转换,只不过还不曾想到前面加和后面加还是有区别的,看来还有很多细节要学习的。
ayb_ice 发表于 2012-2-13 08:31 | 显示全部楼层
...
10000L
100L
...
加L
您需要登录后才可以回帖 登录 | 注册

本版积分规则

49

主题

346

帖子

3

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