gmajvfhpa 发表于 2015-1-10 11:03:41

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

int ia,ib;
long la;
..........
ia = abs(ia);
ib = abs(ib);
la= ia+ib;
........

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

lans0625 发表于 2015-1-10 11:08:35

我觉得没问题,难道还得有个绝对值专用的绝对值数据类型?

haibaogk 发表于 2015-1-10 11:10:29

abs函数本身返回的就是有符号数,这里不会溢出,所以应该没问题。

gmajvfhpa 发表于 2015-1-10 11:14:46

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

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

lans0625 发表于 2015-1-10 11:17:01

gmajvfhpa 发表于 2015-1-10 11:14
问题肯定有,我也是花了一个晚上才发现

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

haibaogk 发表于 2015-1-10 11:29:41

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

lans0625 发表于 2015-1-10 11:35:08

如果有符号数的表示符号的那位是用‘1’表示正数就有问题,相反就没有问题。

modbus 发表于 2015-1-10 11:37:53

肯定有BUG了,-32768取绝对值后是32768,超出int范围了

gmajvfhpa 发表于 2015-1-10 11:38:45

lans0625 发表于 2015-1-10 11:17
什么问题?说说看,不要卖关子。。。。

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

agilityChen 发表于 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才不会有问题。

SealedGhost 发表于 2015-1-10 11:43:44


lz的出的是什么问题呀

zhenghe 发表于 2015-1-10 11:51:07

http://embeddedgurus.com/stack-overflow/2012/02/the-absolute-truth-about-abs/

lans0625 发表于 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)都是错误的。

xiaolaba 发表于 2015-1-10 11:56:54

多放一個 unsign 存你的 ABS 結果, 最高位始終是0

wistarky 发表于 2015-1-10 11:57:45



la= ia+ib;

改成
la = ia;
la += ib;

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

liuchg 发表于 2015-1-10 12:30:56

如果这样呢

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

扬帆远航 发表于 2015-1-10 13:13:06

同意15L的说法..

小行星 发表于 2015-1-10 14:14:20

       11楼真相已出

v灰尘 发表于 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的结果是一样的。

v灰尘 发表于 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的结果是一样的。
--------------------------------------------------------------------------------------------------------------------------------
又试了一下,




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

biansf2001 发表于 2015-1-10 15:17:30

有可能是负数哦亲,溢出就是负数了
页: [1]
查看完整版本: 有符号数,取绝对值后再赋值给有符号数,会有bug吗?