搜索
bottom↓
回复: 20

有符号数,取绝对值后再赋值给有符号数,会有bug吗?

[复制链接]

出0入0汤圆

发表于 2015-1-10 11:03:41 | 显示全部楼层 |阅读模式
int ia,ib;
long la;
..........
ia = abs(ia);
ib = abs(ib);
la= ia+ib;
........

本意是要得到 ia与ib的绝对值之和,这样能得到正确的结果吗?

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

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2015-1-10 11:08:35 | 显示全部楼层
我觉得没问题,难道还得有个绝对值专用的绝对值数据类型?

出0入0汤圆

发表于 2015-1-10 11:10:29 | 显示全部楼层
abs函数本身返回的就是有符号数,这里不会溢出,所以应该没问题。

出0入0汤圆

 楼主| 发表于 2015-1-10 11:14:46 | 显示全部楼层
haibaogk 发表于 2015-1-10 11:10
abs函数本身返回的就是有符号数,这里不会溢出,所以应该没问题。

问题肯定有,我也是花了一个晚上才发现

出0入0汤圆

发表于 2015-1-10 11:17:01 | 显示全部楼层
gmajvfhpa 发表于 2015-1-10 11:14
问题肯定有,我也是花了一个晚上才发现

什么问题?说说看,不要卖关子。。。。

出0入0汤圆

发表于 2015-1-10 11:29:41 | 显示全部楼层
搞不清楚楼主哪里出问题了。可能编译环境不同吧。这里是51单片机分论坛,难道楼主用在51单片机上?那问题是不是51内存溢出啊,int型本来就占4个字节,long型更多,用51做这个,肯定容易出问题,实在不行建议la改为unsigned int

出0入0汤圆

发表于 2015-1-10 11:35:08 | 显示全部楼层
如果有符号数的表示符号的那位是用‘1’表示正数就有问题,相反就没有问题。

出0入0汤圆

发表于 2015-1-10 11:37:53 | 显示全部楼层
肯定有BUG了,-32768取绝对值后是32768,超出int范围了

出0入0汤圆

 楼主| 发表于 2015-1-10 11:38:45 | 显示全部楼层
lans0625 发表于 2015-1-10 11:17
什么问题?说说看,不要卖关子。。。。

int 范围是-32768~32767 ,当变量是-32768取正时,是 +32768,int变量存不了这个数

出0入0汤圆

发表于 2015-1-10 11:40:11 来自手机 | 显示全部楼层
lans0625 发表于 2015-1-10 11:08
我觉得没问题,难道还得有个绝对值专用的绝对值数据类型?

问题大得很。
每一句代码都有问题:
(1) ia = abs(ia); ib = abs(ib);
如果ia或ib为-32768,取绝对值再赋值给int型,直接溢出。
(2) la= ia+ib;
(ia + ib)的类型是int,赋值给Ia时,才转为long。
如果ia + ib已经超过32767或者-32768,就溢出了。
改为Ia = (long)ia + ib才不会有问题。

出0入0汤圆

发表于 2015-1-10 11:43:44 | 显示全部楼层

lz的出的是什么问题呀

本帖子中包含更多资源

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

x

出0入0汤圆

发表于 2015-1-10 11:51:07 | 显示全部楼层
http://embeddedgurus.com/stack-o ... te-truth-about-abs/

出0入0汤圆

发表于 2015-1-10 11:55:58 | 显示全部楼层
agilityChen 发表于 2015-1-10 11:40
问题大得很。
每一句代码都有问题:
(1) ia = abs(ia); ib = abs(ib);

我的理解。
如果用的是最高位'0'表示正,‘1’表示负。
1)不管ia和ib是正还是负,取绝对值后,它们的最高位都是‘0’,ia=abs(ia),ib=abs(ib),还是正确的。
2)因为1)是正确的也是正确的。
如果用的是最高位'1'表示正,‘0’表示负,1),2)都是错误的。

出0入0汤圆

发表于 2015-1-10 11:56:54 | 显示全部楼层
多放一個 unsign 存你的 ABS 結果, 最高位始終是0

出0入0汤圆

发表于 2015-1-10 11:57:45 | 显示全部楼层


la= ia+ib;

改成
la = ia;
la += ib;

ia+ib比int最大正值大的时候会溢位,这时不是用long运算。

出0入0汤圆

发表于 2015-1-10 12:30:56 | 显示全部楼层
如果这样呢

int ia,ib;
unsigned int ua,bu;
long la;
..........
ua = abs(ia);
ub = abs(ib);
la= ua+ub;
........

出0入0汤圆

发表于 2015-1-10 13:13:06 | 显示全部楼层
同意15L的说法..

出0入0汤圆

发表于 2015-1-10 14:14:20 | 显示全部楼层
       11楼真相已出

出0入0汤圆

发表于 2015-1-10 14:32:59 | 显示全部楼层
agilityChen 发表于 2015-1-10 11:40
问题大得很。
每一句代码都有问题:
(1) ia = abs(ia); ib = abs(ib);

“(2) la= ia+ib;
(ia + ib)的类型是int,赋值给Ia时,才转为long。
如果ia + ib已经超过32767或者-32768,就溢出了。
改为Ia = (long)ia + ib才不会有问题。”

在CW下试了一下,没有发现这个问题,就算超过了范围, ia+ib和 (long)ia + ib的结果是一样的。

出0入0汤圆

发表于 2015-1-10 15:01:48 | 显示全部楼层
agilityChen 发表于 2015-1-10 11:40
问题大得很。
每一句代码都有问题:
(1) ia = abs(ia); ib = abs(ib);

“(2) la= ia+ib;
(ia + ib)的类型是int,赋值给Ia时,才转为long。
如果ia + ib已经超过32767或者-32768,就溢出了。
改为Ia = (long)ia + ib才不会有问题。”

在CW下试了一下,没有发现这个问题,就算超过了范围, ia+ib和 (long)ia + ib的结果是一样的。
--------------------------------------------------------------------------------------------------------------------------------
又试了一下,




我猜,和累加器有关,只要结果不超过累加器的范围(位数),就不会出问题。

本帖子中包含更多资源

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

x

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-7-23 10:37

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

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