比较C中的双重值

时间:2012-07-31 19:09:37

标签: c

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

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

4 个答案:

答案 0 :(得分:6)

为了比较双打,您可以使用以下内容:

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

取自here

fabs参考。

但请务必了解potential pitfalls

答案 1 :(得分:4)

不,这不起作用。

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

此外,由于您依赖于截断而不是舍入,您可能会得到不正确的结果(取决于您期望的结果)。 1.0e-71.9e-7将相等(1 == 1),而1.9e-72.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])) {
    ...
}

答案 2 :(得分:1)

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

希望这有帮助。

答案 3 :(得分:0)

当您使用两个浮点值来确定它们理想情况下的值是否相等时,您应该有一些估计(或者更好,一个已证实的界限),如果准确的话,计算值可以相隔多远计算值相等。如果你有这样的界限,那么你可以执行这样的测试:“如果两个数字比错误界限更接近,那么接受它们是相等的。”错误界限可以是一个绝对数字,或者它可能是相对于其中一个值的大小的数字,或者它可能是值的其他一些函数。

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

通常建议制造一些看似很小的门槛并使用它。这是一个草率的编程,而不是工程。

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

相关问题