开发者

When do I use fabs and when is it sufficient to use std::abs?

开发者 https://www.devze.com 2023-01-04 22:33 出处:网络
I assume that abs and fabs are behaving different when using math.h. But when I use just cmath and std::abs, do I ha开发者_运维问答ve to use std::fabs or fabs? Or isn\'t this defined?In C++, it\'s alw

I assume that abs and fabs are behaving different when using math.h. But when I use just cmath and std::abs, do I ha开发者_运维问答ve to use std::fabs or fabs? Or isn't this defined?


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 need fabs for floating point values. These are available in C++ (along with all of the C library), but there's no need to use them.


It's still okay to use fabs for double and float arguments. I prefer this because it ensures that if I accidentally strip the std:: off the abs, 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 of std::abs. I assumed that the using namespace std;would infer std::abs but it did not, and instead was using the C version.

Anyway, I believe it's good to use fabs instead of abs for floating-point inputs as a way of documenting your intention clearly.


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 be std::abs(int) instead of std::abs(float). It's hard to notice.


"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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号