[“正确答案”忽略了选择K
的复杂性。选取K
实际上与选择VISIBLE_SHIFT
一样主观,但选择K
并不像VISIBLE_SHIFT
那样基于任何显示属性。因此你要在选取K
或选取VISIBLE_SHIFT
之间进行抉择。本答案建议选择VISIBLE_SHIFT
,并展示了选择K
的困难之处。]
由于存在舍入误差,您不应该使用“精确”值的比较来进行逻辑操作。在您特定的情况下,对于视觉显示中的位置,0.0或0.0000000003这样微小的差别都无法被肉眼察觉。因此,您的逻辑应该是:
#define VISIBLE_SHIFT 0.0001 // for example
if (fabs(theView.frame.origin.x) < VISIBLE_SHIFT) { /* ... */ }
然而,最终的“肉眼不可见”取决于您的显示属性。如果您可以对显示进行上限约束(应该可以),则选择
VISIBLE_SHIFT
作为该上限的一小部分。
现在,“正确答案”取决于K
,让我们探讨如何选择K
。上述“正确答案”指出:
K是您选择的常数,使得计算中的累积误差在最后一位上明确地受到K个单位的限制(如果您不确定是否正确地计算了误差界限,请将K设为大于计算所需值的几倍)
因此,我们需要K
。如果获取K
比选择我的VISIBLE_SHIFT
更困难、不太直观,那么您就可以决定哪种方法适合您。为了找到K
,我们将编写一个测试程序,查看一堆K
值的行为方式。如果“正确答案”可用,那么选择K
应该很明显,不是吗?
我们将使用上述“正确答案”细节:
if (fabs(x-y) < K * DBL_EPSILON * fabs(x+y) || fabs(x-y) < DBL_MIN)
让我们尝试所有K的值:
#include <math.h>
#include <float.h>
#include <stdio.h>
void main (void)
}
ebg@ebg$ gcc -o test test.c
ebg@ebg$ ./test
K:10000000000000000000000.0000000000000000 -> YES
K: 1000000000000000000000.0000000000000000 -> YES
K: 100000000000000000000.0000000000000000 -> YES
K: 10000000000000000000.0000000000000000 -> YES
K: 1000000000000000000.0000000000000000 -> YES
K: 100000000000000000.0000000000000000 -> YES
K: 10000000000000000.0000000000000000 -> YES
K: 1000000000000000.0000000000000000 -> NO
K: 100000000000000.0000000000000000 -> NO
K: 10000000000000.0000000000000000 -> NO
K: 1000000000000.0000000000000000 -> NO
K: 100000000000.0000000000000000 -> NO
K: 10000000000.0000000000000000 -> NO
K: 1000000000.0000000000000000 -> NO
K: 100000000.0000000000000000 -> NO
K: 10000000.0000000000000000 -> NO
K: 1000000.0000000000000000 -> NO
K: 100000.0000000000000000 -> NO
K: 10000.0000000000000000 -> NO
K: 1000.0000000000000000 -> NO
K: 100.0000000000000000 -> NO
K: 10.0000000000000000 -> NO
K: 1.0000000000000000 -> NO
K: 0.1000000000000000 -> NO
K: 0.0100000000000000 -> NO
K: 0.0010000000000000 -> NO
K: 0.0001000000000000 -> NO
K: 0.0000100000000000 -> NO
K: 0.0000010000000000 -> NO
K: 0.0000001000000000 -> NO
K: 0.0000000100000000 -> NO
K: 0.0000000010000000 -> NO
啊,所以如果我想要1e-13被视为“零”,那么K应该是1e16或更大。
因此,我认为你有两个选项:
1. 使用你的工程判断(如我所建议的)对“epsilon”的值进行简单的epsilon计算。如果你正在做图形,并且“零”意味着“可见变化”,那么请检查你的视觉资产(图像等),并判断epsilon可以是什么值。
2. 先阅读非传统回答的参考资料(并在此过程中获得博士学位),然后使用你的非直观判断来选择K,再尝试浮点运算。