一次印象深刻的float和double的精度Bug处理

平时认为double的精度高一些,float的精度低一些,仅此而已,如果有精度不够的问题就再更换数据类型就好了,不会是什么大问题,现在就看下下图:


一次印象深刻的float和double的精度Bug处理
滤波结果示意图

该图为对一次数据使用22-80hz滤波器后得到的结果,其显示了一个发散的滤波结果。我从各个方面检查问题都无果,包括filter的实现代码,滤波器的设计甚至于各个变量地址的检查,经过了大半天仍然没有头绪。直至发现了滤波器参数是使用float变量存储的时候,我尝试使用double变量改写了参数和滤波器代码,结果就获得了如下的结果:
一次印象深刻的float和double的精度Bug处理
double时的滤波结果示意图

如是,一个持续了几个小时未解决的bug仅仅来源于变量的存储精度。

float和double的精度是由尾数的位数来决定的。浮点数在内存中是按科学计数法来存储的,其整数部分始终是一个隐含着的“1”,由于它是不变的,故不能对精度造成影响。

float:2^23 = 8388608,一共七位,这意味着最多能有7位有效数字,但绝对能保证的为6位,也即float的精度为6~7位有效数字;

double:2^52 = 4503599627370496,一共16位,同理,double的精度为15~16位。

如下图显示了两种存储精度下的滤波器参数:
一次印象深刻的float和double的精度Bug处理
double时的滤波器参数

一次印象深刻的float和double的精度Bug处理
float时的滤波器参数

如上两图,double时的一个参数为-8.53136109628200;float时的一个参数为-8.531360626220703. 其前六位精度相同,但是从第七位开始出现了微小的差距,就是个微小的差距累积导致了开始所说的滤波器无法收敛的情况,导致系统出现了难以解决的问题。

写在后面:本文为原创,如需转载请注明出处https://www.jianshu.com/p/5eac9ac480cb
。欢迎大家留言共同探讨,有误的地方也希望指出。