【问题标题】:C- Floating point precisionC- 浮点精度
【发布时间】:2012-03-06 02:39:10
【问题描述】:

我有一个程序:

int main() 
{   
        float f = 0.0f;  
        int i;  

        for (i = 0 ; i < 10 ; i++) 
                f = f + 0.1f; 

        if (f == 1.0f) 
                printf("f is 1.0 \n"); 
        else 
                printf("f is NOT 1.0\n"); 

        return 0; 
} 

它总是打印f is NOT 1.0。我知道这与 C 中的浮点精度有关。但我不确定它到底在哪里搞砸了。有人可以解释一下为什么它不打印另一行吗?

【问题讨论】:

  • 你自己回答了这个问题。这与精度有关。谷歌会给你1000.001个解释。

标签: c floating-point precision


【解决方案1】:

二进制浮点不能准确地表示值 0.1,因为它的二进制扩展没有有限位数(与 1/7 的十进制扩展完全相同)。

0.1的二进制展开是

0.000110011001100110011001100...

当截断为 IEEE-754 单精度时,这大约是十进制的 0.100000001490116119。这意味着每次将“接近 0.1”的值添加到变量时,都会累积一个小错误 - 因此最终值略高于 1.0

【讨论】:

    【解决方案2】:

    这相当于将 0.33 加在一起 ​​3 倍 (0.99) 并想知道为什么它不等于 1.0。

    您不妨阅读What Every Programmer Should Know About Floating Point Arithmetic

    【讨论】:

      【解决方案3】:

      你不能像这样比较浮点数。您需要定义一个阈值并在此基础上进行比较。 This博文解释

      【讨论】:

      【解决方案4】:

      对于浮点数,在比较它们时应始终使用 epsilon 值:

      #define EPSILON 0.00001f
      
      inline int floatsEqual(float f1, float f2)
      {
          return fabs(f1 - f2) < EPSILON; // or fabsf
      }
      

      【讨论】:

      • Richard,+1,因为我更喜欢独立的答案,但您正在寻找的功能是 fabs 而不是 abs - 我为您解决了这个问题 :-)
      • 谢谢。这有助于并解释了很多。
      • @prasanna 没问题,别忘了接受答案!
      • 因误导“应始终使用”而被否决。使用 epsilon 比较会在浮点值范围上产生不一致的结果。在极值上比较只是一个低效的==。 Epsilon 比较有时会很有用,但只是有时。
      猜你喜欢
      • 2021-09-16
      • 2011-02-23
      • 1970-01-01
      • 2012-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多