我有两个双数组,比如说 A 和 B。我想将它们的结果与 7 个有效数字进行比较。以下是否正确进行比较?
k = pow(10,7);
for(...)
{
if(((int)A[i]*k)!=((int)B[i]*k))
{
...
}
}
我有两个双数组,比如说 A 和 B。我想将它们的结果与 7 个有效数字进行比较。以下是否正确进行比较?
k = pow(10,7);
for(...)
{
if(((int)A[i]*k)!=((int)B[i]*k))
{
...
}
}
不,这行不通。
类型转换运算符的优先级高于乘法运算符。这意味着A[i]
andB[i]
在乘以 1e7 之前将被转换为整数(并被截断)。2.25 和 2.5 最终将等于您的代码。您可以通过将乘法放在括号中来解决此问题:(int)(A[i]*k)
此外,由于您依赖截断而不是四舍五入,您最终可能会得到不正确的结果(取决于您的期望)。1.0e-7
and1.9e-7
将等于 ( 1 == 1
),而1.9e-7
and2.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])) {
...
}
是的,但您必须进行一项更改。尝试 (int)(A[i]*k) 以确保您的乘法首先执行。
希望这可以帮助。
当您使用两个浮点值来确定它们理想情况下的值是否相等时,如果精确计算的值是平等的。如果您有这样的界限,那么您可以执行这样的测试:“如果两个数字比误差界限更接近,则接受它们相等。” 误差界限可以是单个绝对数,也可以是相对于其中一个值的大小的数字,也可以是这些值的某个其他函数。
但是,您还应该回答另一个问题。有时,即使精确计算的值不相等,上述测试也会接受相等的值(因为两个计算值非常接近,甚至可能相等)。因此,您知道即使精确计算的数字不相等,接受彼此接近的计算值是否相等也会给您带来问题。如果答案是肯定的,上述测试有时会接受相同的数字,这会给你带来问题,那么你不能使用这个测试。您可能必须以不同的方式执行计算以减少错误。
经常有人建议制造一些看似很小的阈值并使用它。这是草率的编程,不是工程。
顺便说一句,永远不要写pow(10, 7)
。写1e7
。这避免了函数调用中出现任何错误的可能性,并且可以完全避免不必要的函数调用。