3

我有两个双数组,比如说 A 和 B。我想将它们的结果与 7 个有效数字进行比较。以下是否正确进行比较?

k = pow(10,7);
for(...)
{
 if(((int)A[i]*k)!=((int)B[i]*k))
 {
  ...
 }
}
4

4 回答 4

7

为了比较双打,你可以使用这样的东西:

bool fequal(double a, double b)
{
    return fabs(a-b) < epsilon;
}

取自这里

fabs参考。

但请确保您了解潜在的陷阱

于 2012-07-31T19:25:31.337 回答
5

不,这行不通。

类型转换运算符的优先级高于乘法运算符。这意味着A[i]andB[i]在乘以 1e7 之前将被转换为整数(并被截断)。2.25 和 2.5 最终将等于您的代码。您可以通过将乘法放在括号中来解决此问题:(int)(A[i]*k)

此外,由于您依赖截断而不是四舍五入,您最终可能会得到不正确的结果(取决于您的期望)。1.0e-7and1.9e-7将等于 ( 1 == 1),而1.9e-7and2.1e-7将不 ( 1 != 2)。我建议找到一个可以根据您想要的行为正确舍入的函数。

此外,您的比较不处理有效数字,它只是改变指数的值。在上面的示例中,只有 2 个有效数字,但是您的代码只会比较其中一个数字,因为指数的值为 -7。

这是一些可以满足您要求的代码:

//create integer value that contains 7 significant digits of input number
int adjust_num(double num) {
    double low_bound = 1e7;
    double high_bound = low_bound*10;
    double adjusted = num;
    int is_negative = (num < 0);
    if(num == 0) {
        return 0;
    }
    if(is_negative) {
        adjusted *= -1;
    }
    while(adjusted < low_bound) {
        adjusted *= 10;
    }
    while(adjusted >= high_bound) {
        adjusted /= 10;
    }
    if(is_negative) {
        adjusted *= -1;
    }
    //define int round(double) to be a function which rounds
    //correctly for your domain application.
    return round(adjusted);
}

...

if(adjust_num(A[i]) == adjust_num(B[i])) {
    ...
}
于 2012-07-31T19:23:51.973 回答
1

是的,但您必须进行一项更改。尝试 (int)(A[i]*k) 以确保您的乘法首先执行。

希望这可以帮助。

于 2012-07-31T19:24:31.033 回答
0

当您使用两个浮点值来确定它们理想情况下的值是否相等时,如果精确计算的值是平等的。如果您有这样的界限,那么您可以执行这样的测试:“如果两个数字比误差界限更接近,则接受它们相等。” 误差界限可以是单个绝对数,也可以是相对于其中一个值的大小的数字,也可以是这些值的某个其他函数。

但是,您还应该回答另一个问题。有时,即使精确计算的值不相等,上述测试也会接受相等的值(因为两个计算值非常接近,甚至可能相等)。因此,您知道即使精确计算的数字不相等,接受彼此接近的计算值是否相等也会给您带来问题。如果答案是肯定的,上述测试有时会接受相同的数字,这会给你带来问题,那么你不能使用这个测试。您可能必须以不同的方式执行计算以减少错误。

经常有人建议制造一些看似很小的阈值并使用它。这是草率的编程,不是工程。

顺便说一句,永远不要写pow(10, 7)。写1e7。这避免了函数调用中出现任何错误的可能性,并且可以完全避免不必要的函数调用。

于 2012-07-31T23:35:20.533 回答