Floating point stm32f4上的超小浮点值

Floating point stm32f4上的超小浮点值,floating-point,stm32,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

下面是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
                            );
    }
}
那么,如何处理超小的浮点值呢?我需要它在stm32f4固件中实现Matlab生成的代码,以实现一些过滤功能。

IEEE 754 binary32浮点格式具有24位精度,约为7位十进制数字(由于二进制不是十进制,因此对应不精确)

这不足以区分1和1.00000002。紧邻1.0f上方的二进制32值为1.00000011920928955078125

您可用的选项包括

  • 假设
    double
    映射到具有53位精度的IEEE 754二进制64,则对变量
    sum
    使用类型
    double
    ,或
  • 通过使用更好的求和算法来提高精度。最著名的是:

    void主管道(void)
    {
    浮动总和=1.0;
    uint32_t cnt=0;
    浮点数c=0;
    而(1)
    {
    对于(cnt=0;cnt<1000;cnt++)
    {
    浮子y=2.0e-08f-c;
    浮动t=总和+y;
    c=(t-和)-y;
    总和=t;
    }
    printfUsart(“%f\r\n”,总和);
    }
    }
    

  • 另一种可能性是根据使用的系数优化过滤函数

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

    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
                                );
        }
    }
    
    void主管道(void)
    {
    浮动总和=1.0;
    uint32_t cnt=0,温度=0;
    而(1)
    {
    对于(cnt=0;cnt<1000;cnt++)
    温度+=2;
    总和=总和+温度*e-08;
    printfUsart(“%f\r\n”,
    总和
    );
    }
    }
    

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

    我认为void main()可以,因为我们有一个嵌入式微控制器。不需要返回一个值,因为主体没有调用线程或OS。使用浮点,肯定使用Kahan-Sand,但是也考虑在循环之前(和之前)乘以10 ^ 6或10 ^ 8…然后再分割。这通常是在固定点解决类似问题的方式。
    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);
      }
    }
    
    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
                                );
        }
    }