何时使用 fabs 以及何时使用 std::abs 就足够了?
我假设使用 math.h
时 abs
和 fabs
的行为不同。但是,当我只使用 cmath
和 std::abs
时,我是否必须使用 std::fabs
或 fabs
>?还是这个没有定义?
I assume that abs
and fabs
are behaving different when using math.h
. But when I use just cmath
and std::abs
, do I have to use std::fabs
or fabs
? Or isn't this defined?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
在 C++ 中,使用 std::abs 总是足够的;它对于所有数字类型都是重载的。
在 C 中,
abs
仅适用于整数,而您需要fabs
来处理浮点值。这些在 C++ 中可用(以及所有 C 库),但没有必要使用它们。In C++, it's always sufficient to use
std::abs
; it's overloaded for all the numerical types.In C,
abs
only works on integers, and you needfabs
for floating point values. These are available in C++ (along with all of the C library), but there's no need to use them.使用
fabs
作为double
和float
参数仍然可以。我更喜欢这个,因为它可以确保如果我不小心将std::
从abs
上剥离,浮点输入的行为保持不变。我只花了 10 分钟调试这个问题,因为我自己错误地使用了
abs
而不是std::abs
。我假设using namespace std;
会推断std::abs
但它没有,而是使用 C 版本。不管怎样,我相信对于浮点输入使用 fabs 而不是 abs 是很好的方式,可以清楚地记录您的意图。
It's still okay to use
fabs
fordouble
andfloat
arguments. I prefer this because it ensures that if I accidentally strip thestd::
off theabs
, that the behavior remains the same for floating point inputs.I just spent 10 minutes debugging this very problem, due to my own mistake of using
abs
instead ofstd::abs
. I assumed that theusing namespace std;
would inferstd::abs
but it did not, and instead was using the C version.Anyway, I believe it's good to use
fabs
instead ofabs
for floating-point inputs as a way of documenting your intention clearly.还有一个原因明确推荐使用
std::fabs
进行浮点输入。如果您忘记包含,您的
std::abs(my_float_num)
可以是std::abs(int)
而不是std::abs (浮动)
。很难注意到。There is one more reason to recommend
std::fabs
for floating-point inputs explicitly.If you forget to include <cmath>, your
std::abs(my_float_num)
can bestd::abs(int)
instead ofstd::abs(float)
. It's hard to notice.“abs”和“fabs”仅对于 C++ 浮点类型来说是相同的,此时它们可以在没有不明确的重载消息的情况下进行翻译。
我正在使用 g++ (g++-7)。
与模板使用一起,特别是在使用 mpreal 时,有时会出现硬“模糊过载”消息 -
abs(static_cast(x))
并不总是能解决这个问题。当abs不明确时,晶圆厂有可能按预期工作。对于 sqrt 我发现没有这样简单的转义。
几周以来,我一直在努力解决 C++“不存在的问题”。我正在将旧的 C++ 程序更新为 C++14,以获得比以前更多更好的模板使用。通常,相同的模板参数可能是实际的任何标准浮点或复杂类型或类类型。为什么,长双重行为比其他类型更明智一些。
一切正常,我之前已经包含了 mpreal。
然后我将默认浮点类型设置为 mpreal 并遇到了大量语法错误。
这产生了数千个不明确的重载,例如对于abs和sqrt,迫切需要不同的解决方案。有些需要重载的帮助函数,但在模板之外。必须使用零或一或 type_cast 将 0.0L 和 1.0L 的一千个用法分别替换为精确的常量类型 - 由于不明确,自动转换定义不可能。
到五月为止,我发现现有的隐式转换非常好。
但更简单的是,没有任何类型,并且具有安全显式 type_casts 到任何其他标准常量类型的类型保存常量。
"abs" and "fabs" are only identical for C++ float types, when they can be translated without ambiguous overload messages.
I'm using g++ (g++-7).
Together with template usage and especially when using mpreal there are cases with hard "ambiguous overload" messages -
abs(static_cast<T>(x))
isn't always solving that.When abs is ambiguous, there are chances that fabs is working as expected. For sqrt I found no such simple escape.
Since weeks I'm hard struggling on C++ "not existing problems". I'm updating an old C++ program to C++14 for more and better template usage than possible before. Often the same template parameter may be actual any standard float or complex type or a class type. Why ever, long double acted somewhat more sensible than other types.
All was working, and I had included mpreal before.
Then I was setting my default float type to mpreal and got a deluge of syntax errors.
That gave thousands of ambiguous overloads e.g. for abs and sqrt, crying for different solutions. Some were needing overloaded help functions, but outside of a template. Had to replace individually a thousand usages of 0.0L and 1.0L with the exact constant type using Zero or One or a type_cast - automatic conversion definition impossible because of ambiguities.
Up to May I found the existing of implicit conversions very nice.
But much simpler it would be without any, and to have typesave constants with safe explicit type_casts to any other standard constant type.