我有两个双数组,比方说A和B.我想将他们的结果与7位有效数字进行比较。以下是否正确进行比较?
k = pow(10,7);
for(...)
{
if(((int)A[i]*k)!=((int)B[i]*k))
{
...
}
}
答案 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-7
和1.9e-7
将相等(1 == 1
),而1.9e-7
和2.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
。这避免了函数调用中出现任何错误的可能性,并且可以完全避免不必要的函数调用。