为什么“使用命名空间 std;”在 C++ 中处理双精度时会产生不同的结果?

Why "using namespace std;" gives different result when dealing with doubles in C++?

提问人:silverfox 提问时间:6/25/2021 最后编辑:silverfox 更新时间:6/25/2021 访问量:234

问:

今天,当我遇到一个奇怪的结果时,我正试图回答这篇文章(关于检查是否可以构造三角形)。

通过测试,这段代码:15.15 35.77 129.07

#include <iostream>
using namespace std;

const double e = 0.000001;

void f(double a, double b, double c)
{
    if (abs(180 - (a+b+c)) > e) {cout << "test"; }
}

int main()
{
    double a,b,c; cin >> a >> b >> c;
    f(a,b,c);
}

照常打印,而这:test

#include <iostream>
const double e = 0.000001;

void f(double a, double b, double c)
{
    if (abs(180 - (a+b+c)) > e) {std::cout << "test"; }
}

int main()
{
    double a,b,c; std::cin >> a >> b >> c;
    f(a,b,c);
}

不。唯一的区别是行(当我添加到第二段代码时,正如预期的那样,它运行正常)。using namespace std;using namespace std;

随着时间的推移,我读了很多关于的帖子:using namespace std;

但似乎唯一要做的就是偷工减料,以换取偶尔的类/变量/命名空间名称冲突(在争论是否使用它时最常提到的一点)。using namespace std;

我确实找到了 1 个相关帖子:为什么 g++(4.6 和 4.7)将这种除法的结果提升为双倍?我可以阻止它吗?,但我在其他地方没有找到更多信息。

那么我在这里错过了什么?

-- 一些机器信息:

  • Windows 10,64 位
  • 代码::Blocks 20.03
  • GCC/G++ 6.3.0 版本
C++ 命名空间 double std

评论

2赞 NathanOliver 6/25/2021
FWIW,您的代码具有未定义的行为。 不住在 中,并且您尚未包含所需的标头。最有可能的是,您正在引入不同的函数,甚至可能是宏与函数。abs<iostream>abs
0赞 Richard Critten 6/25/2021
对案例 (2) 有一些警告 - 实时 - godbolt.org/z/W4c81ssb7 这应该解释
1赞 Eljay 6/25/2021
第二个示例无法在我的机器上编译,缺少.我添加并更改为 .它打印了.abs#include <cmath>absstd::abstest
1赞 Eljay 6/25/2021
@YSC • 还没有准备好进入黄金时段,因为它们不完整(大约 50% 的标准C++标题)。尚未在 github 上分享。我称我的项目为死文件,因为它们只是存根,没有太多的实现方式。 也把我搞砸了,因为它们对编译时评估不友好。它们仅适用于 C++14,因为这就是我目前正在从事的工作(不是出于选择,我宁愿现在转到 C++17,尽快转到 C++20......但我的项目卡在 C++14 中)。constexpr
1赞 JaMiT 6/25/2021
避免用户在示例代码中输入通常是个好主意。鉴于公认的答案,我认为您没有尝试用 ?这不仅可以更轻松地重现您的结果,而且还会消除一个发挥作用的地方。double a,b,c; std::cin >> a >> b >> c;double a = 15.15, b = 35.77, c = 129.07;namespace std

答:

1赞 Jorengarenar 6/25/2021 #1

那是因为你没有添加 ,因此编译器并不真正知道它是什么函数,因此 UB。它很可能已经找到并使用了 C 版本的函数,该函数是为参数而制作的。std::abs()int

7赞 YSC 6/25/2021 #2

确实存在名称冲突:int abs(int) 与 double std::abs(double)。

使用 ,可以找到两者,并且是更好的匹配项。using namespace std;abs(180 - (a+b+c))std::abs

没有 ,只找到前者,并且需要转换为,因此观察到的行为。using namespace std;abs(180 - (a+b+c))int

你真正想要的是:

#include <iostream>
const double e = 0.000001;

void f(double a, double b, double c)
{
    if (std::abs(180 - (a+b+c)) > e) {std::cout << "test"; }
}

int main()
{
    double a,b,c; std::cin >> a >> b >> c;
    f(a,b,c);
}

评论

2赞 YSC 6/25/2021
请注意,您还可以用于显式记录您不使用整数版本的意图。std::fabs
0赞 silverfox 6/25/2021
啊,我明白了。所以我找到的帖子确实对这个案子有一些权利。我真的困惑了一段时间。