C ++如何更精确地计算双变量?

问题描述

我认为G ++编译器存在双重操作问题。

我正在尝试测试某些程序,并发现在double(==)比较中存在错误。 因此,我阅读了一些文章,发现双重比较应该适用于比较EPSILON(非常小的数字)https://stackoverflow.com/a/17341/7105963

我写了下面的代码,但是没有按预期工作。

如您在主代码中看到的,我向函数is_same()发送了双参数A和A + EPSILON。由于if条件,显然(在数学上)std::abs(A - (A + EPSILON)) = std::abs(EPSILON),这应该返回false。但是,它会在G ++(9.3.0)中返回true(1)。

而且A + EPSILON也不计算。它只返回A中的std::cout。有什么功能可以更精确地计算双变量吗?

代码

#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,3,4) << "\n";
    std::cout << std::fixed << "EPSILON(small)\t\t" << __DBL_EPSILON__ << "\n";
    std::cout << std::fixed << "distance + EPSILON\t" << (distance(0,4) + __DBL_EPSILON__) << "\n";
    std::cout << std::fixed << "distance - EPSILON\t" << (distance(0,4) - __DBL_EPSILON__) << "\n";
    // std::cout << is_same(distance(0,4),(distance(0,4) + __DBL_EPSILON__)) << "\n";
    std::cout << is_same(distance(0,4) + __DBL_EPSILON__)) << "\n";
}

输出

dist (0,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

环境

  • Docker GCC(9.3.0)(精确来说是G ++ 9.3.0)

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)