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::abs
和 std::fabs
在应用于浮点值时是否有任何区别?
Is there any difference at all between std::abs and std::fabs when applied to floating point values?
不,没有。整数类型也没有区别。
使用 std::abs()
是惯用的,因为它最接近常用的数学术语。
在包含 cmath
的 standard-conforming 代码中,仅在 float
、double
和 long double
上调用 std::abs
, 没有区别。但是,当您使用包含的各种 header 文件集调用它时,查看 std::abs
在各种类型上返回的类型是有指导意义的。
在我的系统上,如果我包含 cmath
而不是 cstdlib
,std::abs(-42)
是 double
,如果我包含 int
cstdlib
,如果我两者都不包含,它会产生编译错误。相反,如果我包含 cstdlib
但没有包含 cmath
或其他编译错误(从未听说过 std::abs
,std::abs(-42.0)
会产生编译错误(不明确的重载) ) 如果我两者都没有包含。
在我的平台上,如果我包含 cmath
,std::abs('x')
会给我一个 double
,如果我包含 cstdlib
,则会给我一个 int
,但是不是 cmath
。 short 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
。
有一个 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::abs
和 std::fabs
在应用于浮点值时是否有任何区别?
Is there any difference at all between std::abs and std::fabs when applied to floating point values?
不,没有。整数类型也没有区别。
使用 std::abs()
是惯用的,因为它最接近常用的数学术语。
在包含 cmath
的 standard-conforming 代码中,仅在 float
、double
和 long double
上调用 std::abs
, 没有区别。但是,当您使用包含的各种 header 文件集调用它时,查看 std::abs
在各种类型上返回的类型是有指导意义的。
在我的系统上,如果我包含 cmath
而不是 cstdlib
,std::abs(-42)
是 double
,如果我包含 int
cstdlib
,如果我两者都不包含,它会产生编译错误。相反,如果我包含 cstdlib
但没有包含 cmath
或其他编译错误(从未听说过 std::abs
,std::abs(-42.0)
会产生编译错误(不明确的重载) ) 如果我两者都没有包含。
在我的平台上,如果我包含 cmath
,std::abs('x')
会给我一个 double
,如果我包含 cstdlib
,则会给我一个 int
,但是不是 cmath
。 short 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
。