In C++, std::abs is overloaded for both signed integer and floating point types. std::fabs only deals with floating point types (pre C++11). Note that the std:: is important; the C function ::abs that is commonly available for legacy reasons will only handle int!

The problem with

Copyfloat f2= fabs(-9);

is not that there is no conversion from int (the type of -9) to double, but that the compiler does not know which conversion to pick (int -> float, double, long double) since there is a std::fabs for each of those three. Your workaround explicitly tells the compiler to use the int -> double conversion, so the ambiguity goes away.

C++11 solves this by adding double fabs( Integral arg ); which will return the abs of any integer type converted to double. Apparently, this overload is also available in C++98 mode with libstdc++ and libc++.

In general, just use std::abs, it will do the right thing. (Interesting pitfall pointed out by @Shafik Yaghmour. Unsigned integer types do funny things in C++.)

Answer from Baum mit Augen on Stack Overflow
Top answer
1 of 3
49

In C++, std::abs is overloaded for both signed integer and floating point types. std::fabs only deals with floating point types (pre C++11). Note that the std:: is important; the C function ::abs that is commonly available for legacy reasons will only handle int!

The problem with

Copyfloat f2= fabs(-9);

is not that there is no conversion from int (the type of -9) to double, but that the compiler does not know which conversion to pick (int -> float, double, long double) since there is a std::fabs for each of those three. Your workaround explicitly tells the compiler to use the int -> double conversion, so the ambiguity goes away.

C++11 solves this by adding double fabs( Integral arg ); which will return the abs of any integer type converted to double. Apparently, this overload is also available in C++98 mode with libstdc++ and libc++.

In general, just use std::abs, it will do the right thing. (Interesting pitfall pointed out by @Shafik Yaghmour. Unsigned integer types do funny things in C++.)

2 of 3
19

With C++ 11, using abs() alone is very dangerous:

Copy#include <iostream>
#include <cmath>

int main() {
    std::cout << abs(-2.5) << std::endl;
    return 0;
}

This program outputs 2 as a result. (See it live)

Always use std::abs():

Copy#include <iostream>
#include <cmath>

int main() {
    std::cout << std::abs(-2.5) << std::endl;
    return 0;
}

This program outputs 2.5.

You can avoid the unexpected result with using namespace std; but I would adwise against it, because it is considered bad practice in general, and because you have to search for the using directive to know if abs() means the int overload or the double overload.

🌐
Reddit
reddit.com › r/cpp_questions › difference between abs() and fabs(), and can i replace with each other in the program?? and abs() fn is kinda not working.....
r/cpp_questions on Reddit: Difference between abs() and fabs(), and can i replace with each other in the program?? And abs() fn is kinda not working.....
November 26, 2019 - fabs is one of a family of type-specific names from C. The C++ standard libraries provide these names, fabsf for float, fabs for double and fabsl for long double, for compatibility with C, so that barring other issues C code that uses these ...
Discussions

c++ - When do I use fabs and when is it sufficient to use std::abs? - Stack Overflow
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? More on stackoverflow.com
🌐 stackoverflow.com
fabs versus abs? - C++ Forum
I would like to know why there's 3 math functions to calculate the absolute value of a number: fabs(), labs() and abs(), this last one is for integral types. I think this is a completely stupid thing. It doesn't matter what kind of number we have, the steps to achieve the absolute value are ... More on cplusplus.com
🌐 cplusplus.com
June 22, 2014
c++ - Is there any difference between std::abs and std::fabs when applied to floating point values? - Stack Overflow
There is a related question but I believe it doesn't answer this question. Looking at std::abs and std::fabs documentation they seems to have exactly the same behaviour. As a personal note, it app... More on stackoverflow.com
🌐 stackoverflow.com
Fabs and abs
Try simply this: [code]#if 1 /* 0 or 1 / #include // for “abs” #include // for “fabs” #else / 0 or 1 / #include // for “std::abs” and “std::fabs” #endif / 0 or 1 */ · You should have got it by now that there’s no “default c++ behaviour” what concerns ... More on root-forum.cern.ch
🌐 root-forum.cern.ch
0
0
July 10, 2012
🌐
Cppreference
en.cppreference.com › w › cpp › numeric › math › fabs.html
std::abs(float), std::fabs, std::fabsf, std::fabsl - cppreference.com
1-4) Computes the absolute value of the floating-point value num. The library provides overloads of std::abs and std::fabs for all cv-unqualified floating-point types as the type of the parameter num.(since C++23)
🌐
Quora
quora.com › What-is-the-difference-between-abs-and-fabs-function
What is the difference between abs() and fabs() function? - Quora
The only difference between both of them is, abs() is used to calculate the absolute value for integer type numbers whereas fabs() are used for floating type numbers. abs() function is use un...
🌐
Cplusplus
cplusplus.com › forum › beginner › 136274
fabs versus abs? - C++ Forum
June 22, 2014 - C++ provides overload of abs() for all arithmetic types. fabs() and labs() are provided for backward compatibility with C, which does not have function overloading and had to have different fucntions for different types.
Top answer
1 of 2
15

In standard-conforming code that has included cmath and only calls std::abs on floats, doubles, and long doubles, there is no difference. However, it is instructive to look at the types returned by std::abs on various types when you call it with various sets of header files included.

On my system, std::abs(-42) is a double if I've included cmath but not cstdlib, an int if I've included cstdlib, and it produces a compilation error if I've included neither. Conversely, std::abs(-42.0) produces a compilation error (ambiguous overload) if I've included cstdlib but I haven't included cmath or a different compilation error (never heard of std::abs) if I've included neither.

On my platform, std::abs('x') gives me a double if I've included cmath or an int if I've included cstdlib but not cmath. Similar for a short int. Signedness does not appear to matter.

On my platform, the complex header apparently causes both the integral and the floating-point overloads of std::abs to be declared. I'm not certain this is mandated; perhaps you can find an otherwise reasonable platform on which std::abs(1e222) returns infinity with the wrong set of standard headers included.


The usual consequence of "you forgot a header in your program" is a compilation failure complaining of an undefined symbol, not a silent change in behaviour. With std::abs, however, the result can be std::abs(42) returning a double if you forgot cstdlib or std::abs('x') returning an int if you didn't. (Or perhaps you expected std::abs to give you an integral type when you pass it a short? Then, assuming my compiler got its promotion and overload resolution right, you had better make sure you don't include cmath.)

I have also spent too much time in the past trying to work out why code like double precise_sine = std::sin(myfloat) gives imprecise results. Because I don't like wasting my time on these sorts of surprises, I tend to avoid the overloaded variants of standard C functions in namespace std. That is, I use ::fabs when I want a double to be returned, ::fabsf when I want a float out, and ::fabsl when I want a long double out. Similarly for ::abs when I want an int, ::absl when I want a long, and ::absll when I want a long long.

2 of 2
0

Is there any difference at all between std::abs and std::fabs when applied to floating point values?

No there is not. Nor is there a difference for integral types.

It is idiomatic to use std::abs() because it is closest to the commonly used mathematical nomenclature.

🌐
CERN
root-forum.cern.ch › t › fabs-and-abs › 14556
Fabs and abs - ROOT - ROOT Forum
July 10, 2012 - in cint it seems that abs and fabs are different function root [6] abs(1.2234234) (const int)1 root [7] fabs(1.2234234) (const double)1.22342339999999994e+00 but this is not the behaviour of c++ codepad.org/gM7JzQ2…
Find elsewhere
🌐
Codecademy
codecademy.com › docs › c++ › math functions › fabs()
C++ (C Plus Plus) | Math Functions | fabs() | Codecademy
April 13, 2025 - In this example, fabs() is used ... floating-point precision issues: ... fabs() is designed for floating-point types (float, double, long double) while abs() is typically used with integer types....
🌐
SACO Evaluator
saco-evaluator.org.za › docs › cppreference › en › cpp › numeric › math › fabs.html
std::abs(float), std::fabs - cppreference.com
If successful, returns the absolute value of arg (|arg|). The value returned is exact and does not depend on any rounding modes. This function is not subject to any of the error conditions specified in math_errhandling · If the implementation supports IEEE floating-point arithmetic (IEC 60559), ... Between C++11 and C++14, the standard erroneously required std::abs to have overloads for integer types returning double.
🌐
CodeSpeedy
codespeedy.com › home › difference between fabs and abs function in c++
Difference between fabs and abs function in C++ - CodeSpeedy
September 14, 2022 - The difference between the fabs() and abs() function is that fabs() function is used for floating values and abs() function is used for integer values. abs() function returns the absolute value for the integer.
Top answer
1 of 1
49

The official references say... it's a mess. Pre-C++11 and C11:

  • Officially, including <cmath> introduced nothing in ::; all of the functions were in std::. Practically, only export was less respected, and different compilers did very different things. If you included <cmath>, you used std:: everywhere, or what you got varied from compiler to compiler.

  • C didn't provide any overloads: abs took an int, and was declared in <stdlib.h>, fabs took double, and was declared in <math.h>.

  • If you included <math.h> in C++, it's not clear what you got, but since none of the implementers seemed to care about the standard anyway (see the first point above)...

Roughly speaking, either you included <cmath>, and prefixed all of the uses with std::, or you included <math.h>, and used fabs if you wanted support for floating point (and the various suffixes for types other than int or double).

C++11 and C11 added a few new twists:

  • <cmath> is now allowed (but not required) to introduce the symbols in :: as well. One more thing which can vary depending on the implementation. (The goal here was to make existing implementations conformant.)

  • C has a new header, <tgmath.h>, which uses compiler magic to make the functions in <math.h> behave as if they were overloaded as in C++. (So it doesn't apply to abs, but only to fabs.) This header had not been added to C++, for the obvious reason that C++ doesn't need any compiler magic for this.

All in all, the situation has become slightly worse, and my recommendations above still hold. Include either <math.h> and <stdlib.h>, and use abs/fabs and their derivated (e.g. labs, fabsf, etc.) exclusively, or include <cmath>, and use std::abs exclusively. Anything else, and you'll run into portabiity problems.

🌐
Youth4work
youth4work.com › talent › c language › forum › what is the difference between abs() and fabs() functions?
What is the difference between abs() and fabs() functions?
November 16, 2015 - Close · Sandeep · 27 Jun · Both functions are to retrieve absolute value. abs() is for integer values and fabs() is for floating type numbers. Prototype for abs() is under the library file < stdlib.h > and fabs() is under < math.h >. 0 Comments ...
🌐
Studiofreya
studiofreya.com › 2014 › 07 › 04 › beware-of-the-difference-between-abs-and-stdabs
Beware of the difference between ::abs and std::abs | Studio Freya
July 4, 2014 - If you only use ::abs with floating point variables, you’ll risk an implicit cast to an integral value (short, int, long). This won’t be converted to std::abs even if you include using namespace std; Be safe, use ::fabs, std::abs or std::fabs, but not ::abs.
🌐
NVIDIA Developer Forums
forums.developer.nvidia.com › accelerated computing › hpc compilers › legacy pgi compilers
abs() vs fabs() - Legacy PGI Compilers - NVIDIA Developer Forums
December 25, 2010 - Hi, I noticed that the C++ compiler (pgCC 10.3-0 64-bit target on x86-64 Linux -tp shanghai-64) behaves somewhat unexpectedly when trying to compile #include int main() { double a = 5.0; std::abs(a); return 0; } The error message "test-fabs.cpp", line 6: error: more than one instance of overloaded function "std::abs" matches the argument list: function "abs(int)" function "std::abs(long double)" argument types are: (double) ...
🌐
Coin-or
coin-or.org › CppAD › Doc › abs.htm
AD Absolute Value Functions: abs, fabs
x is an AD type, this is an atomic operation . Complex Types The functions · abs and · fabs are not defined for the base types · std::complex<float> or · std::complex<double> because the complex · abs function is not complex differentiable (see complex types faq ).