浮点精度与实际分配的值不匹配?

Aka*_*kay 0 c floating-point

我正在研究STM32F777 mcu在FreeRTOS上创建应用程序.STM32F777带有双精度浮点单元.我在使用浮点单元时发现这个非常烦人的问题,当我使用常量或其他东西为浮点值赋值时,例如:

float x = 78.352361;
Run Code Online (Sandbox Code Playgroud)

调试时我看到分配给变量x的实际值是:78.3523636

类似地,当我将17.448636分配给变量x时,我在调试时实际看到的是17.4486351.

任何想法,为什么会发生这种情况以及如何解决这个问题?我希望保持正确的精度直到6位数.

Eri*_*hil 5

最常见的浮点格式,IEEE 754,包括基本32位格式和基本的64位格式,并且这些通常用于floatdouble类型C.为了简便起见,我会请他们floatdouble在此答案.

这些类型都不能精确地表示非整数,而不是2的幂的倍数(例如,¼,¾,1/1024,33/1048576).当从十进制转换为float或时,每个其他数字都会略有变化double.

但是,float具有以六位有效数字(例如1.2345或9.87654e23)舍入任何十进制数字float并返回六位有效十进制数字的属性返回原始数字(假设数字在格式的正常范围内).在C中,该数字由数据报告FLT_DIG,其定义为float.h.由于您的电话号码78.352361有8位有效数字,不保证能够继续保留至float往返时间.

对于double,至少有15位将生存往返,通过报道DBL_DIG.

请注意,这是由于一次转换为二进制浮点并返回到原始的十进制数字而导致的舍入不变的十进制数.如果在浮点中执行附加算术运算,则会发生其他舍入,这可能会累积更多错误.并且,如果使用比原始值更多的十进制数字格式化值,则结果可能与原始数字不同.(例如,.9f当转换回一个十进制数字时产生".9",而当转换为九个十进制数字时产生"0.899999976".)

由于double保证15位数在往返中存活,因此您的号码78.352361将在转换double为8位有效数字后保持不变.此外,有足够的精度来执行某些算术,而不会累积太多错误,以便在八位有效十进制数字中可见.但是,浮点运算可能很棘手,完整的错误分析取决于您执行的操作.