引言

在目前的大部分编程语言中,浮点数的实现标准都是以 IEEE-754 的标准实现的。所以,在比较两个浮点数大小关系时,直接进行比较可能会获得意料之外的答案。所以浮点数在四则运算中是不满足分配律和结合律的

这里 IEEE-754 标准就不具体叙述了,见上面维基百科。

2 进制的浮点数表示有一个很大的问题:它并不能精确表示所有实数。只有可以写成2a+2b+2c+...2^a+2^b+2^c+... 这种形式,并且精度要求不是特别高的实数才可以用浮点数来精确表示。所以大多数实数仅仅保存了一个四舍五入后的近似值。比如,0.1 在单精度浮点数中实际值是 0.100000001490116119384765625

如何进行比较呢?

正因为上述原因,所以实际上我们对两个浮点数进行比较时,是利用做差的方式来比较。

假设有两个浮点数 a 和 b,假设我们要求精度保证是4位,那么我们可以设置一个误差值eps

一般它的值为1e-(要求精度 + 2),我们这里 eps = 1e-6

那么这个误差值有什么用呢?这个误差是用来进行精度保证的。

这样,我们可以假设 a - b的值落在[-eps, eps]这个闭区间内时,即可认定a == b

那么根据集合运算的原理,我们可以很容易写出所有比较的情况:

  1. a == b, 判断方式:(a - b) >= -eps && (a - b) <= eps;
  2. a > b, 判断方式:(a - b) > eps;
  3. a < b, 判断方式:(a - b) < -eps;
  4. a >= b, 判断方式:(a - b) >= -eps; (情况1和情况2取并集)
  5. a <= b, 判断方式:(a - b) <= eps; (情况1和情况3取并集)

这样,我们确定了一个 eps 后,就能很好的进行浮点数的比较而不会因为精度而受影响了。