stm32f4上的超小浮点值

时间:2015-03-05 15:35:39

标签: floating-point stm32

这是stm32f4的简单代码

void main(void)
{
    float sum = 1.0;
    uint32_t cnt = 0;

    while(1)
    {
        for( cnt = 0; cnt < 1000; cnt++ )
            sum += 2.0e-08;

        printfUsart("%f\r\n", 
                            sum
                            );
    }
}

变量sum值没有变化。 如果我循环汇总这个值:sum += 2.0e-07;它会增加。 我使用&#34; gcc-arm-none-eabi-4_9-2014q4&#34;编译器使用此编译器和链接器标志:

PROCESSOR = -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16

那么,如何使用超小浮点值?我需要它在stm32f4固件中实现Matlab生成的代码来实现一些过滤功能。

2 个答案:

答案 0 :(得分:2)

IEEE 754 binary32 浮点格式具有24位精度,大约为7位十进制数字(对应关系不准确,因为二进制不是十进制)。

这还不足以区分1和1.00000002。紧靠1.0f以上的binary32值为exactly 1.00000011920928955078125。

您的可用选项

  1. 使用类型double作为变量sum,假设double以53位精度映射到IEEE 754 binary64 ,或者< / LI>
  2. 通过使用更好的求和算法来提高准确性。最着名的是Kahan's

    void main(void)
    {
      float sum = 1.0;
      uint32_t cnt = 0;
      float c = 0;
    
      while(1)
      {
        for( cnt = 0; cnt < 1000; cnt++ )
        {
            float y = 2.0e-08f - c;
            float t = sum + y;
            c = (t - sum) - y;
            sum = t;
        }
    
        printfUsart("%f\r\n", sum);
      }
    }
    

答案 1 :(得分:0)

另一种可能性是针对使用的系数优化滤波功能。

以下是手动优化示例的解决方案:

void main(void)
{
    float sum = 1.0;
    uint32_t cnt = 0, temp = 0;

    while(1)
    {
        for( cnt = 0; cnt < 1000; cnt++ )
            temp += 2;
        sum = sum + temp*e-08;

        printfUsart("%f\r\n", 
                            sum
                            );
    }
}

缺点是,您必须手动执行此优化并且它不是通用的,但它可以节省大量计算时间,因为浮点运算较少。