eguy 发表于 2009-7-9 02:16:20

AVR里,用C语言做这样的运算a=(191*b-28872)/(1204-0.38*b) 能精确到多少?(已解决)

其中a b均定义成无符号整型,, 这里的乘法和除法是C语言里的,最后换成AVR去执行的时候它是如何保证那么长的数据? 是按需要开RAM来对付吗?
如果是按虚开RAM,那乘法和除法的过程是否会因为AVR内部的资源问题导致输出不够精确呢?

jackielau 发表于 2009-7-9 08:17:38

我记得以前试过,如果运算过程中出现了long型,那可能就要舍弃高位了,你的结果就不正确了!

wenpeijun 发表于 2009-7-9 08:35:01

闹心的数据类型转换啊!强烈建议楼主自己用单片机做下试验,你就会发现很多公式运算后都不是你想要的结果!

eguy 发表于 2009-7-9 08:49:13

的确相差非常遥远,我让b=1024 结果应该是a=204,实际为43

ilcvm 发表于 2009-7-9 09:12:25

加些强制类型转换,多试几次就清楚该怎么做了。
这个跟是否用AVR无关,结果不准主要是C语言本身的运算时所用的类型转换规则所致。

dr2001 发表于 2009-7-9 09:14:41

既然已经出现浮点数了,那就考虑这么搞:
a=(unsigned long)((191.0*b-28872.0)/(1204.0-0.38*b))
这样的情况下,如果结果没有溢出,那么最多能有Float那么多个有效数字。自己考虑考虑。

因为涉及到C默认的类型转换,所以你这么干,编译后的代码,极大可能是这么计算的:
1 整数计算 ans1 = 191*b,然后整数算ans1 - 28872
2 浮点计算 ans2 = 0.38*b,然手1204转换浮点,计算1204-ans2
3 上边的两个结果转换浮点,计算除法
4 除法结果转换定点。
精度的丢失丢在第一那个整数上,如果溢出就完蛋。
完全不是你想象的方法。

另外,不知道你说的 无符号整型 是 unsigned long 还是 unsigned int。AVR上,前者32Bit,后者16Bit。
uint的话,那么191×1024就已经溢出了。结果对了就怪了。

weuser 发表于 2009-7-9 09:18:17

将b定义成unsigned long.

eguy 发表于 2009-7-9 09:27:07

感谢大家 问题解决 的确可能是溢出
解决办法是把a和b都设置成unsigned long (根据dr2001 提示)

eguy 发表于 2009-7-9 09:51:29

wenpeijun的建议也很好

xuyulei008 发表于 2014-3-20 21:24:38

{:lol:}               
页: [1]
查看完整版本: AVR里,用C语言做这样的运算a=(191*b-28872)/(1204-0.38*b) 能精确到多少?(已解决)