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

Ant*_*nio 3 c++ floating-point absolute-value

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

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

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

tmy*_*ebu 6

在已列入符合标准的代码,cmath并且只要求std::absfloatS,doubleS,和long doubleS,没有什么区别。但是,std::abs当您在包含各种头文件集的情况下调用它时,查看各种类型返回的类型是有益的。

在我的系统上,std::abs(-42)doubleif Ive Include cmathbut not cstdlibintif Ive Include cstdlib,如果我都没有包括,它会产生编译错误。相反,std::abs(-42.0)如果我包括cstdlib但我没有包括cmath或不同的编译错误(从未听说过),如果我没有包括,则会产生编译错误(模棱两可的重载)std::abs

在我的平台,std::abs('x')给了我double,如果我已经包含cmathint如果我包括cstdlib但不限cmath。类似于short int. 签名似乎并不重要。

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


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

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