参考至:
http://bbs.csdn.net/topics/320026823
https://msdn.microsoft.com/en-us/library/c151dt3s(VS.71).aspx
加上我上一篇说明浮点数表示方法 :
http://blog.csdn.net/l773575310/article/details/52788866
(epsilon,希腊语字母的第五个字母)
有时候计算机判断(1.0 == 10.0 / 10.0)的时候,并不总是返回true。因为浮点数计算可能会产生一定点误差,而这误差是无法避免的。正确的做法是判断两个值是否在这个误差范围内,而误差范围就是从正FLT_EPSILON 到负FLT_EPSILON 内。(1.0 > (10.0 / 10.0) - FLT_EPSILON && 1.0 < (10.0 / 10.0) + FLT_EPSILON)。
FLT_EPSILON 在 float.h 头文件 宏定义如下
#define FLT_EPSILON 1.192092896e-07F // smallest such that 1.0+FLT_EPSILON != 1.0
后面的注释可以理解为 这个数是 能使 (1.0 + FLT_EPSILON != 0) 成立的最小的数
也就是说 小于FLT_EPSILON 的数 加上 1.0 都等于 1.0
浮点数 1.0 表示为
符号位 0 (1位), 阶码 27-1 + 0 (8位), 尾数 1000 0000 0000 0000 0000 0000 (23位 尾数第一个1 省略 ,参考上一篇)
0 0111 1111 000 0000 0000 0000 0000 0000
最小能大于1.0的数 就是 3f80 0001
最后这个1 就是 2-23 的
也就是(卧槽,windows10自带计算器,比FLT_EPSILON 精确好多)
个人理解 : 这个宏 FLT_EPSILON 就是因为计算机不能精确存储二进制浮点数 ,在计算两个值
如 参考上面链接的提问
int main() { float a, b, c; a = 1.345f; b = 1.123f; c = a + b; // if (FLOAT_EQ(c, 2.468)) // Remove comment for correct result if (c == 2.468) // Comment this line for correct result printf("They are equal.\n"); else printf("They are not equal! The value of c is %13.10f,or %f",c,c); }结果是
They are not equal! The value of c is 2.4679999352 or 2.468000.
For EPSILON, you can use the constants FLT_EPSILON, which is defined for float as 1.192092896e-07F, or DBL_EPSILON, which is defined for double as 2.2204460492503131e-016. You need to include float.h for these constants. These constants are defined as the smallest positive number x, such that x+1.0 is not equal to 1.0. Because this is a very small number, you should employ user-defined tolerance for calculations involving very large numbers.
需要一个容差(就是FLT_EPSILON )来弥补精度问题引发偏差
PS:双精度型也有
#define DBL_EPSILON 2.2204460492503131e-016 // smallest such that 1.0+DBL_EPSILON != 1.0