C++ C++;如何更精确地计算双变量?
我认为G++编译器中有一个关于双重操作的问题 我试图测试一些程序,在比较(=)double时发现了错误。 所以,我读了一些文章,发现双重比较应该与比较ε(非常小的数字)一起使用 我编写了如下代码,但它没有像我预期的那样工作 正如您在主代码中看到的,我将双参数A和A+ε发送到函数C++ C++;如何更精确地计算双变量?,c++,double,comparison,operators,precision,C++,Double,Comparison,Operators,Precision,我认为G++编译器中有一个关于双重操作的问题 我试图测试一些程序,在比较(=)double时发现了错误。 所以,我读了一些文章,发现双重比较应该与比较ε(非常小的数字)一起使用 我编写了如下代码,但它没有像我预期的那样工作 正如您在主代码中看到的,我将双参数A和A+ε发送到函数is_same()。由于if条件,显然(数学上)std::abs(A-(A+EPSILON))=std::abs(EPSILON),这应该返回false。但是,它在G++(9.3.0)中返回true(1) 而且,A+EPS
is_same()
。由于if条件,显然(数学上)std::abs(A-(A+EPSILON))=std::abs(EPSILON)
,这应该返回false。但是,它在G++(9.3.0)中返回true(1)
而且,A+EPSILON
不计算。它只是在std::cout
中返回A
。有没有更精确地计算双变量的函数
代码
#包括
#包括
布尔是一样的(双倍x,双倍y){
如果(标准::abs(\uuuux-\uuuuy)<\uuuuuu DBL\u EPSILON\uuuuu){
STD:CUD< C++ >代码,但不是你所想的。StAccOfFuff.com问题你引用的参考文献 EpSimon ,而不是<>代码>这似乎与手头的任务有关,从不同的程序集中起来不太可能产生预期的结果。@SamVarshavchik感谢您的回答。我理解您所说的EPSILON
和\uu DBL\u EPSILON\uuuu>是不同的,也不应该在不理解概念的情况下组合许多其他代码。但是,我不明白为什么distance+EPSILON
和distance-EPSILON
没有像我预期的那样工作。正如我所知,\uuu DBL\u EPSILON\uuu
只是定义了一个双倍数,即(double)2.22044604925031308084726333618164062e-16L
。这意味着,仅仅是双倍运算并不能准确工作。请告诉我原因:(请阅读\uuuu DBL\u EPSILON\uuuu
的定义。当添加到1.0
时,它是产生一个不同数字的最小增量。这意味着根据定义,在比较浮点数时,不能有任何更小的差异。尝试确定比\uu DBL\u EPSILON\uu更小的差异e> 将永远注定要失败,因为根据定义,它们在数学上是不可能存在的。这回答了你的问题吗?@Jeffrey我已经知道这个基于浮点数据结构的问题。我想我找到了答案。作为@Sam Varshavchik,我对\uu DBL\u EPSILON\uu
#include <iostream>
#include <cmath>
bool is_same(double __x, double __y) {
if(std::abs(__x - __y) < __DBL_EPSILON__) {
std::cout << std::fixed << "IN Function __x\t\t" << __x << "\n";
std::cout << std::fixed << "IN Function __y\t\t" << __y << "\n";
std::cout << std::fixed << "std::abs(__x - __y)\t" << std::abs(__x - __y) << "\n";
return true;
} else {
return false;
}
}
double distance(double x1, double y1, double x2, double y2) {
return std::sqrt(std::pow((x2 - x1), 2) + std::pow((y2 - y1), 2));
}
int main() {
std::cout.precision(17); // maximum precision : https://stackoverflow.com/a/554134/7105963
std::cout << std::fixed << "dist (0, 0) ~ (3, 4)\t" << distance(0, 0, 3, 4) << "\n";
std::cout << std::fixed << "EPSILON(small)\t\t" << __DBL_EPSILON__ << "\n";
std::cout << std::fixed << "distance + EPSILON\t" << (distance(0, 0, 3, 4) + __DBL_EPSILON__) << "\n";
std::cout << std::fixed << "distance - EPSILON\t" << (distance(0, 0, 3, 4) - __DBL_EPSILON__) << "\n";
// std::cout << is_same(distance(0, 0, 3, 4), (distance(0, 0, 3, 4) + __DBL_EPSILON__)) << "\n";
std::cout << is_same(distance(0, 0, 3, 4), (distance(0, 0, 3, 4) + __DBL_EPSILON__)) << "\n";
}
dist (0, 0) ~ (3, 4) 5.00000000000000000
EPSILON(small) 0.00000000000000022
distance + EPSILON 5.00000000000000000
distance - EPSILON 5.00000000000000000
IN Function __x 5.00000000000000000
IN Function __y 5.00000000000000000
std::abs(__x - __y) 0.00000000000000000
1