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?

- 2,999
- 2
- 31
- 47

- 8,514
- 10
- 53
- 61
4 Answers
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.

- 249,747
- 28
- 448
- 644
-
Is this on every platform the case? Esp. Windows and Mac OS X? Or is it at least in the C++ standard? – math Jun 25 '10 at 13:09
-
3@brubelsabs: yes. There is no need for a separate fabs function in C++ since C++ has function overloading (abs can be defined for numerous types and it is in C++). It is also guaranteed by the standard. Of course if you dig around find some outdated compiler over 10 years old, you might find one that doesn't support it. – stinky472 Jun 25 '10 at 13:13
-
1It's in the C++ Standard, so it's the case on every platform with a decent compiler, including Windows and Mac OS X. Clause 26.5 says that, in addition to the `int` version from the C library, there are overloads for `long`, `float`, `double` and `long double`. Clause 26.2.7 also defines an overload for `complex`. – Mike Seymour Jun 25 '10 at 13:18
-
6If you forget the `std::` and just use `abs`, your code will work as expected on windows but will use the `int` version on linux, which can be incredibly hard to debug. – Adversus Nov 03 '15 at 08:52
-
"*all* the numerical types" [citation needed]. I can see int, long, long long, std::intmax_t, float, double, long double. No short or char versions (or unsigned versions) that I can see. – user673679 Mar 02 '20 at 17:41
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.

- 12,223
- 16
- 74
- 116
-
2That's weird. Your call should've been ambiguous (and thus an error) right? – Nick Jan 12 '13 at 15:57
-
Shouldn't you be using fabsf for float? So I don't think they are identical. – Nick Jan 26 '13 at 19:53
-
1Beware of Android NDK g++, it also cedes to c abs() function instead of std::abs(). In Visual Studio c++ compiler however abs always points to std::abs() though. – Kurovsky Nov 05 '15 at 11:06
-
@Nick, I think I agree with you: I don't seem to get that behaviour of Alan Turing i.e. for me the overloaded `std::abs` always seems to be invoked (and not the C-version of `abs`) when calling `abs` as long as `using namespace std;` is explicated at the beginning. I don't know if this is compiler specific though. – MaviPranav Dec 26 '16 at 22:31
-
@Nick is not an error as there is a function name that matches. It is implementation defined which one will be chosen. – Pato Sandaña Aug 30 '19 at 13:38
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.

- 131
- 1
- 3
"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.

- 11
- 3