std::abs 和 std::fabs 应用于浮点值时有什么区别吗?

Is there any difference between std::abs and std::fabs when applied to floating point values?

有一个 related question 但我认为它没有回答这个问题。

正在查看 std::abs and std::fabs documentation they seems to have exactly the same behaviour. As a personal note, it appears to me that std::fabs is preferable because it mitigates the ambiguity with the std::abs(int) definition in <cstdlib>(See note)。

所以我的问题是:除了 std::abs(int) 潜在的歧义外,std::absstd::fabs 在应用于浮点值时是否有任何区别?

Is there any difference at all between std::abs and std::fabs when applied to floating point values?

不,没有。整数类型也没有区别。

使用 std::abs() 是惯用的,因为它最接近常用的数学术语。

在包含 cmath 的 standard-conforming 代码中,仅在 floatdoublelong double 上调用 std::abs , 没有区别。但是,当您使用包含的各种 header 文件集调用它时,查看 std::abs 在各种类型上返回的类型是有指导意义的。

在我的系统上,如果我包含 cmath 而不是 cstdlibstd::abs(-42)double,如果我包含 int cstdlib,如果我两者都不包含,它会产生编译错误。相反,如果我包含 cstdlib 但没有包含 cmath 或其他编译错误(从未听说过 std::absstd::abs(-42.0) 会产生编译错误(不明确的重载) ) 如果我两者都没有包含。

在我的平台上,如果我包含 cmathstd::abs('x') 会给我一个 double,如果我包含 cstdlib,则会给我一个 int,但是不是 cmathshort int 类似。签名似乎并不重要。

在我的平台上,complex header 显然会导致声明 std::abs 的积分和 floating-point 重载。我不确定这是强制性的;也许您可以找到一个其他合理的平台,在该平台上 std::abs(1e222) returns 包含错误的标准集 header infinity。


"you forgot a header in your program" 的通常结果是编译失败并抱怨未定义的符号,而不是行为上的无声更改。然而,对于 std::abs,如果您忘记了 cstdlib,结果可能是 std::abs(42) 返回 double,或者如果您没有忘记 std::abs('x'),则返回 int吨。 (或者你可能希望 std::abs 在你传递 short 时给你一个整数类型?然后,假设我的编译器得到了正确的提升和重载解析,你最好确保你不包括cmath.)

我过去也花了太多时间试图找出为什么像 double precise_sine = std::sin(myfloat) 这样的代码会给出不精确的结果。因为我不喜欢在这些惊喜上浪费时间,所以我倾向于避免在 namespace std 中使用标准 C 函数的重载变体。也就是说,当我想要返回 double 时我使用 ::fabs,当我想要返回 float 时使用 ::fabsf,当我想要 ::fabsl 时=14=]出来。同样,当我想要 int::abs,当我想要 long::absl,当我想要 long long::absll