4

有一个相关的问题,但我相信它不能回答这个问题。

查看std::absstd::fabs记录它们似乎具有完全相同的行为。作为个人笔记,在我看来这std::fabs是更可取的,因为它减轻了(见)中std::abs(int)定义的歧义。<cstdlib>

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

4

2 回答 2

7

在包含cmath且仅调用s、s 和s 的符合标准的代码中std::abs,没有区别。但是,当您调用它并包含各种头文件集时,查看各种类型返回的类型是有益的。floatdoublelong doublestd::abs

在我的系统std::abs(-42)上,double如果我已经包含cmath但不包含cstdlibint如果我已经包含cstdlib,如果我没有包含,它会产生编译错误。相反,如果我已经包含但我没有包含,std::abs(-42.0)则会产生编译错误(不明确的重载),或者如果我没有包含,则会产生不同的编译错误(从未听说过)。cstdlibcmathstd::abs

在我的平台上,std::abs('x')给我一个doubleif I've includedcmath或一个intif I've included cstdlibbut not cmath。类似的short int。签名似乎并不重要。

在我的平台上,complex标头显然会导致声明的积分和浮点重载std::abs。我不确定这是强制性的;也许您可以找到一个其他合理的平台,在该平台上std::abs(1e222)返回无穷大并包含错误的标准标头集。


“您忘记了程序中的标头”的通常后果是编译失败并抱怨未定义的符号,而不是行为的无声变化。但是,如果您忘记了std::abs,结果可能会std::abs(42)返回 a ,如果您没有double忘记cstdlib,则std::abs('x')返回 an int。(或者你可能希望std::abs在传递 a 时给你一个整数类型short?那么,假设我的编译器正确地得到了它的提升和重载解析,你最好确保你不包含cmath。)

过去我也花了太多时间试图弄清楚为什么类似代码double precise_sine = std::sin(myfloat)会给出不精确的结果。因为我不喜欢把时间浪费在这些惊喜上,所以我倾向于避免namespace std. 也就是说,我::fabs在想要double返回 a 时使用,::fabsf当我想要floatout 时以及::fabsl想要out 时使用long double。同样,::abs当我想要一个int::absl当我想要一个long::absll当我想要一个long long

于 2015-12-10T04:46:26.997 回答
0

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

No there is not. Nor is there a difference for integral types.

It is idiomatic to use std::abs() because it is closest to the commonly used mathematical nomenclature.

于 2015-12-09T20:06:55.103 回答