【问题标题】:When do I use fabs and when is it sufficient to use std::abs?我什么时候使用 fabs,什么时候使用 std::abs 就足够了?
【发布时间】:2011-03-08 06:50:49
【问题描述】:

我假设absfabs 在使用math.h 时表现不同。但是当我只使用cmathstd::abs 时,我是否必须使用std::fabsfabs?还是没有定义?

【问题讨论】:

    标签: c++ math.h cmath


    【解决方案1】:

    在 C++ 中,使用 std::abs 总是足够的;它对所有数字类型都重载了。

    在 C 中,abs 仅适用于整数,而浮点值需要 fabs。这些在 C++ 中可用(以及所有 C 库),但没有必要使用它们。

    【讨论】:

    • 每个平台都是这样吗?特别是。 Windows 和 Mac OS X?还是至少在 C++ 标准中?
    • @brubelsabs:是的。在 C++ 中不需要单独的 fabs 函数,因为 C++ 具有函数重载(abs 可以为多种类型定义,并且它在 C++ 中)。它也是由标准保证的。当然,如果你四处寻找一些超过 10 年的过时编译器,你可能会发现一个不支持它的。
    • 它在 C++ 标准中,所以在每个平台上都有一个像样的编译器,包括 Windows 和 Mac OS X。除了 C 库中的 int 版本之外,第 26.5 条说,longfloatdoublelong double 存在重载。第 26.2.7 条还定义了 complex 的重载。
    • 如果您忘记了std:: 而只使用abs,您的代码将在Windows 上按预期运行,但在Linux 上将使用int 版本,这很难调试。
    • 所有数字类型”[需要引用]。我可以看到 int、long、long long、std::intmax_t、float、double、long double。我看不到 short 或 char 版本(或未签名版本)。
    【解决方案2】:

    fabs 仍然可以用于 doublefloat 参数。我更喜欢这个,因为它可以确保如果我不小心将std::abs 中剥离,浮点输入的行为仍然相同。

    我只花了 10 分钟调试这个问题,因为我自己错误地使用了 abs 而不是 std::abs。我认为 using namespace std; 会推断出 std::abs 但它没有,而是使用 C 版本。

    无论如何,我认为使用 fabs 而不是 abs 进行浮点输入是一种很好的方式,可以清楚地记录您的意图。

    【讨论】:

    • 这很奇怪。你的电话应该是模棱两可的(因此是一个错误)对吧?
    • 您不应该使用 fabsf 进行浮动吗?所以我不认为它们是相同的。
    • 当心 Android NDK g++,它也让步给 c abs() 函数而不是 std::abs()。然而,在 Visual Studio c++ 编译器中,abs 总是指向 std::abs()。
    • @Nick,我想我同意你的观点:我似乎不明白艾伦图灵的那种行为,即对我来说,重载的 std::abs 似乎总是被调用(而不是 C 版本abs) 调用 abs 时,只要在开头说明 using namespace std;。我不知道这是否是特定于编译器的。
    • @Nick 不是错误,因为存在匹配的函数名称。选择哪一个由实现定义。
    【解决方案3】:

    还有一个理由明确推荐 std::fabs 用于浮点输入。

    如果您忘记包含 ,您的 std::abs(my_float_num) 可以是 std::abs(int) 而不是 std::abs(float)。很难注意到。

    【讨论】:

      【解决方案4】:

      "abs" 和 "fabs" 仅对于 C++ 浮点类型是相同的,因为它们可以在没有歧义的重载消息的情况下进行翻译。

      我正在使用 g++ (g++-7)。 连同模板的使用,尤其是在使用 mpreal 时,有些情况下会出现“模棱两可的过载”消息——abs(static_cast<T>(x)) 并不总是能解决这个问题。 当 abs 不明确时,fabs 有可能按预期工作。对于 sqrt,我发现没有这么简单的转义。

      几周以来,我一直在努力解决 C++“不存在的问题”。我正在将一个旧的 C++ 程序更新为 C++14,以便比以前更多更好地使用模板。通常,相同的模板参数可能是实际的任何标准浮点或复杂类型或类类型。为什么,长的双重行为比其他类型更明智。 一切正常,我之前已经包含了 mpreal 。 然后我将我的默认浮点类型设置为 mpreal 并得到了大量的语法错误。 这给了数以千计的模棱两可的重载,例如对于 abs 和 sqrt,需要不同的解决方案。有些需要重载的帮助功能,但在模板之外。必须使用 Zero 或 One 或 type_cast 将 0.0L 和 1.0L 的一千个用法单独替换为精确的常量类型 - 由于歧义,无法进行自动转换定义。

      截至 5 月,我发现隐式转换的存在非常好。 但更简单的是,没有任何类型,并且使用安全显式 type_casts 到任何其他标准常量类型的类型保存常量。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-10-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多