我必须使用STM32的距离传感器的测量结果来计算2个浮点数。通过以下等式进行计算;
结果=(df-ds)/ ds * 10000;
其中df是第一次测量,ds是第二次测量。
方程式的样本值;
df = 26.6810; ds = 25.3270;
我的问题是,这些值的STM32结果为 534.578247 ,但是当我在Windows计算器上手动进行计算时,得到的结果却是 534.607336 ,这与STM32的计算。我还使用了一个手动计算器,并且手动计算器与计算机给出的结果完全相同。
所有变量在程序中都声明为float。 为什么两个计算之间有如此大的差异? 为了使STM32产生更精确的结果,我可以进行哪些更改?
在此先感谢您的帮助。
编辑:我正在使用的代码如下;
float result= 0;
dmbres = 27.4587;
int main()
{
while(1)
{
result= (float)((dmbres- res)/res)*10000;
dmbres = res;
sprintf(datapackage, "%d;%.4f;%.6f\r\n", mid, res,result);
monitor(datapackage);
}
数据包包含我需要从MCU接收的其他2条信息,它们与结果计算无关。
我正在使用STM32F407 DISC-1开发板。
答案 0 :(得分:1)
您具有以下代码:
float result= 0;
dmbres = 27.4587;
int main()
{
while(1)
{
result= (float)((dmbres- res)/res)*10000;
dmbres = res;
sprintf(datapackage, "%d;%.4f;%.6f\r\n", mid, res,result);
monitor(datapackage);
}
您给出了以下等式:
结果=(df-ds)/ ds * 10000;
具有以下值:
df = 26.6810; ds = 25.3270;
您报告了以下结果:
结果= 534.578247
我假设以下情况:
为df
( 26.6810 )显示的值来自变量res
到字符串的转换:
sprintf(datapackage, "%d;%.4f;%.6f\r\n", mid, res,result);
由于此输出字符串将四舍五入到小数点后四位,因此它来自的float res
值可以是 26.680950164794921875 到 26.6810474395751953125 。这将为循环的下一次迭代形成dmbres
值。
为ds
( 25.3270 )显示的值来自在循环的下一次迭代中将变量res
转换为字符串。由于此输出字符串也被四舍五入到小数点后四位,因此它来自的float res
值可以是 25.3269500732421875 至 25.3270473480224609375 范围内的任何值。
result
( 534.578247 )显示的值来自变量result
到字符串的转换,
sprintf(datapackage, "%d;%.4f;%.6f\r\n", mid, res,result);
此输出字符串对于float
非常精确。最接近的存储值为 534.5782470703125 。
对于df
和ds
的可能值,result = (df-ds)/ds*10000
的最小可能值由(26.680950164794921875-25.3270473480224609375)/ 25.3270473480224609375 * 10000 给出,并且(26.6810474395751953125-25.3269500732421875)/ 25.3269500732421875 * 10000 给出了最大值。
从这两个表达式得出的最接近的float
值分别为 534.5679931640625 和 534.6468505859375 。您的 534.5782470703125 的实际结果在此范围内,因此并不意外。
答案 1 :(得分:0)
正如其他人所提到的,数字“太接近”。 32位浮点数使用23位作为有效位,因此仅约7个有效十进制数字。例如1234567。您可以将小数点放在任何地方,但7以后的任何数字都不精确,尤其是在使用它们执行计算之后。 64位double使用52位,并保留约16个十进制数字。
因此您可以将变量声明为double。这样可以为您提供更大的精度范围,但执行速度会慢得多。