[“正确答案”掩盖了选择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
所以让我们探索picking 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)
{
double x = 1e-13;
double y = 0.0;
double K = 1e22;
int i = 0;
for (; i < 32; i++, K = K/10.0)
{
printf ("K:%40.16lf -> ", K);
if (fabs(x-y) < K * DBL_EPSILON * fabs(x+y) || fabs(x-y) < DBL_MIN)
printf ("YES\n");
else
printf ("NO\n");
}
}
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 或更大。
所以,我会说你有两个选择:
- 正如我所建议的,使用您对“epsilon”值的工程判断进行简单的 epsilon 计算。如果您正在做图形并且“零”意味着是“可见的变化”,而不是检查您的视觉资产(图像等)并判断 epsilon 可以是什么。
- 在您阅读非货物崇拜答案的参考(并在此过程中获得博士学位)之前,不要尝试任何浮点计算,然后使用您的非直觉判断来选择
K
.