应用于浮点值时,std::abs 和 std::fabs 之间有啥区别吗?
Posted
技术标签:
【中文标题】应用于浮点值时,std::abs 和 std::fabs 之间有啥区别吗?【英文标题】:Is there any difference between std::abs and std::fabs when applied to floating point values?应用于浮点值时,std::abs 和 std::fabs 之间有什么区别吗? 【发布时间】:2015-12-09 18:00:46 【问题描述】:有一个related question,但我相信它不能回答这个问题。
看看std::abs
and std::fabs
documentation,他们似乎有完全相同的行为。作为个人说明,在我看来std::fabs
更可取,因为它减轻了<cstdlib>
中std::abs(int)
定义的歧义(参见note)。
所以我的问题是:除了 std::abs(int)
潜在的歧义之外,std::abs
和 std::fabs
在应用于浮点值时有什么区别吗?
【问题讨论】:
还有***.com/questions/33738509/… 不知道你怎么看不到。std::abs
和 std::fabs
具有相同的行为。
【参考方案1】:
在包含cmath
并且仅在float
s、double
s 和long double
s 上调用std::abs
的符合标准的代码中,没有区别。但是,当您调用 std::abs
并包含各种头文件集时,查看 std::abs
在各种类型上返回的类型是有益的。
在我的系统上,std::abs(-42)
是 double
,如果我已包含 cmath
但不是 cstdlib
,如果我已包含 int
,则为 int
,如果我包含'没有包括。相反,如果我包含了cstdlib
但我没有包含cmath
或其他编译错误(从未听说过std::abs
),则std::abs(-42.0)
会产生编译错误(不明确的重载),如果我没有包含两者。
在我的平台上,如果我包含了cmath
,std::abs('x')
会给我一个double
,或者如果我包含了cstdlib
而不是cmath
,则给我一个int
。与short int
类似。签名似乎无关紧要。
在我的平台上,complex
标头显然会导致声明 std::abs
的整数和浮点重载。我不确定这是强制性的;也许您可以找到一个其他合理的平台,在该平台上 std::abs(1e222)
返回无穷大,但包含错误的标准标头集。
“您忘记了程序中的标头”的通常后果是编译失败并抱怨未定义的符号,而不是行为的无声变化。但是,使用std::abs
,如果您忘记了cstdlib
,结果可能是std::abs(42)
返回double
,或者如果您没有忘记std::abs('x')
,则返回int
。 (或者,当您将 short
传递给它时,您可能希望 std::abs
给您一个整数类型?那么,假设我的编译器正确地进行了提升和重载解析,您最好确保不包含 cmath
。 )
过去我也花了太多时间试图弄清楚为什么像double precise_sine = std::sin(myfloat)
这样的代码会给出不精确的结果。因为我不喜欢在这些惊喜上浪费时间,所以我倾向于避免namespace std
中标准 C 函数的重载变体。也就是说,当我想要返回 double
时,我使用 ::fabs
,当我想要 float
时使用 ::fabsf
,当我想要 long double
时使用 ::fabsl
。对于::abs
,当我想要int
,::absl
,当我想要long
,::absll
,当我想要long long
。
【讨论】:
【参考方案2】:当应用于浮点值时,std::abs 和 std::fabs 之间有什么区别吗?
不,没有。整数类型也没有区别。
使用std::abs()
是惯用的,因为它最接近常用的数学命名法。
【讨论】:
以上是关于应用于浮点值时,std::abs 和 std::fabs 之间有啥区别吗?的主要内容,如果未能解决你的问题,请参考以下文章
Visual Studio 单元测试:为啥在测试相同的浮点值时测试运行不确定?
(Rcpp)armadillos abs() 函数在 std::abs 工作时与 c++ double 一起使用时输出错误值