搜索
bottom↓
回复: 30

Keil C51 运算 *10000,数据老溢出,什么问题?

[复制链接]

出0入0汤圆

发表于 2013-10-25 22:43:32 | 显示全部楼层 |阅读模式
啥不说,上图




而 *100000都不会谥出,就在10000出问题



试了下用浮点型数据也是一样,谥出



程序调了一个多小时才发现这问题,,,仿真一下,吓了身汗,不知道我做出去的产品有没有用到这种 *10000 



本帖子中包含更多资源

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

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2013-10-25 22:57:44 | 显示全部楼层
本帖最后由 zuu0 于 2013-10-25 23:01 编辑

为什么错误出现在*10000 其它点十万,百万的都没问题,就一万有问题,并且在40000以后就不对了

目前解决方法,只有在乘 10000这个点上 强制转换成 10000L

出0入0汤圆

发表于 2013-10-25 23:25:01 | 显示全部楼层
a5=5*10000;
改写成:
a5=5;
a5*=10000;  试试

正规的写法应该是:  a5=5*(unsigned long int)10000;

出0入0汤圆

发表于 2013-10-25 23:25:04 | 显示全部楼层
原因不是很显然么?
C51里面的int是2个字节,10000是int类型,4*10000还是int类型,但是溢出了就是。

出0入0汤圆

 楼主| 发表于 2013-10-25 23:44:36 | 显示全部楼层
本帖最后由 zuu0 于 2013-10-26 00:21 编辑

上面意思是不是说,我这个10000 决定了,我这4*10000 5*10000 6*10000 7*10000 8*10000 9*10000的数据类型都是int型 所以有谥出,应该是7.8.9谥出才对啊


而如果*100000, 100000是long int 所以,9*10000数据都是long int 不会谥出

出0入0汤圆

发表于 2013-10-25 23:52:34 | 显示全部楼层
学习,学习!

出0入0汤圆

发表于 2013-10-25 23:53:03 来自手机 | 显示全部楼层
有道理                  

出0入0汤圆

发表于 2013-10-26 00:01:02 来自手机 | 显示全部楼层
本帖最后由 erpao 于 2013-10-26 00:03 编辑

位运算?

出0入0汤圆

发表于 2013-10-26 00:08:35 | 显示全部楼层
这个Bug都是你自己的C语言水平不够造成的,原因其实很简单,就以第一个错误为例,在C语言里面常数不加l、f限定的话一律按照int类型处理(8位单片机int一般是16位宽,32位机是32位宽),而且常数的运算在编译阶段已经被优化了。
a4=4*10000与a4=40000完全等效,40000的16进制是0x9c40,
也就是a4=0x9c40,注意0x9c40这个16位宽的int型常量最高位是1,也就是负数,而a4是32位宽的long类型,根据符号位扩展,a4被赋予的值是0xffff9c40,也就是你看到的4294941760。

到这里为止一切都真相大白了。

出0入0汤圆

 楼主| 发表于 2013-10-26 00:20:39 | 显示全部楼层
schwarz 发表于 2013-10-26 00:08
这个Bug都是你自己的C语言水平不够造成的,原因其实很简单,就以第一个错误为例,在C语言里面常数不加l、f ...



非常感谢啊,学习了! 看来平时自己用的时候都太随意了。。不规范的写法, 搞不好程序里就隐含的这种致命的Bug

出0入0汤圆

发表于 2013-10-26 02:53:08 来自手机 | 显示全部楼层
不过单片机一般都使用unsigned 类型吧?

出0入0汤圆

发表于 2013-10-26 07:59:06 来自手机 | 显示全部楼层
真相大白,c语言任重道远

出0入0汤圆

发表于 2013-10-26 08:15:26 | 显示全部楼层
我只使用unsigned型 ,自己判断有没有溢出。

出0入0汤圆

发表于 2013-10-26 09:09:00 | 显示全部楼层
学习学习

出0入4汤圆

发表于 2013-10-26 10:10:41 | 显示全部楼层
对Keil C51平台不熟悉酿成的血案

出0入0汤圆

发表于 2013-10-26 10:31:03 | 显示全部楼层
zuu0 发表于 2013-10-25 23:44
上面意思是不是说,我这个10000 决定了,我这4*10000 5*10000 6*10000 7*10000 8*10000 9*10000的数 ...

int16_t 的数据范围是-32768~32767,4万就已经溢出了。

出0入0汤圆

发表于 2013-10-26 10:35:35 | 显示全部楼层
valley 发表于 2013-10-26 10:31
int16_t 的数据范围是-32768~32767,4万就已经溢出了。

那为什么100000没溢出?

出0入21汤圆

发表于 2013-10-26 10:43:04 | 显示全部楼层
我也遇到类似情况,今天才得明白,看来c路甚长

出0入0汤圆

发表于 2013-10-26 11:51:41 | 显示全部楼层
这问题我也碰到过

出0入0汤圆

发表于 2013-10-26 12:03:19 | 显示全部楼层
本帖最后由 valley 于 2013-10-26 12:09 编辑
avrwoo 发表于 2013-10-26 10:35
那为什么100000没溢出?


编译器编译的时候发现10w超出了int但没有超出long,便用long存储。

从编译器设计者的角度来看,10w不能用int存储是很容易发现便处理的,这个时候可以选择用long来存储它;而1w*4溢出处理的问题,我们注意到1w和4都没有超出int的范围,而是相乘之后的结果超出了,一是编译器比较难以发现这方面的错误,二是可能要付出较大的代价。
另一方面,C语言规范里面对类型提升已经做了规定,2个int类型相乘的结果还是int类型,编译器这样处理逻辑上说得通。能不能避免这样的错误就就要看使用者的水平了。

出0入0汤圆

发表于 2013-10-26 12:37:07 | 显示全部楼层
valley 发表于 2013-10-26 12:03
编译器编译的时候发现10w超出了int但没有超出long,便用long存储。

从编译器设计者的角度来看,10w不能 ...

明白了。谢谢!

出0入0汤圆

发表于 2013-11-26 16:01:45 | 显示全部楼层
受教了,好贴!

出0入0汤圆

发表于 2013-11-27 11:25:09 | 显示全部楼层
学习了,试了下定义一个unsigned int类型变量TEST并赋值为10000,这时4*TEST结果没溢出,看来只对常量运算才会出现在这样的结果

出0入0汤圆

发表于 2014-4-12 15:23:15 | 显示全部楼层
学习 了

出0入0汤圆

发表于 2014-4-12 23:28:07 | 显示全部楼层
学习了,mark

出0入0汤圆

发表于 2014-4-15 09:29:22 | 显示全部楼层
int16_t 的数据范围是-32768~32767,4万就已经溢出了。

出0入10汤圆

发表于 2016-4-22 11:44:02 | 显示全部楼层
学习了,感谢楼上

出0入0汤圆

发表于 2016-4-22 17:13:04 | 显示全部楼层
schwarz 发表于 2013-10-26 00:08
这个Bug都是你自己的C语言水平不够造成的,原因其实很简单,就以第一个错误为例,在C语言里面常数不加l、f ...

受教了~

出0入0汤圆

发表于 2016-4-22 17:26:47 | 显示全部楼层
学习了,感谢

出0入0汤圆

发表于 2016-4-28 16:16:13 | 显示全部楼层
以前也遇到过,后来重新看了c99标准的书就极少出这种问题了。然而现在最新的是c11标准......

出0入8汤圆

发表于 2016-4-28 16:34:32 | 显示全部楼层
10000要写成10000L的。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-29 08:45

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表