C-浮点精度
我有一个程序:
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中的浮点精度有关。但我不确定它到底搞砸了。 有人可以解释一下为什么不打印另一条线?
二进制浮点不能精确地表示值0.1,因为它的二进制扩展没有有限的数字位数(与1/7的十进制扩展不完全相同)。
二进制扩展为0.1
0.000110011001100110011001100...
当截断为IEEE-754单精度时,这约为0.100000001490116119
(十进制)。 这意味着每次向变量添加“接近0.1”值时,都会累积一个小错误 – 因此最终值略高于1.0
。
你不能比较像这样的浮动。 您需要定义阈值并根据该阈值进行比较。 这篇博客文章解释道
这相当于将0.33加在一起3次(0.99),并想知道为什么它不等于1.0。
您可能希望阅读每个程序员应该知道的关于浮点运算的内容
对于浮点数,在比较它们时应始终使用epsilon值:
#define EPSILON 0.00001f inline int floatsEqual(float f1, float f2) { return fabs(f1 - f2) < EPSILON; // or fabsf }