Beware, I am talking about ::abs()
, not std::abs()
According to the cplusplus.com website, abs
is supposed to behave differently for the stdlib.
h C version, if you include <cmath>
Here is an extract from the this page (which deals with ::abs
, not std::abs
):
double abs (double x); float abs (float x); long double abs (long double x); Compute absolute value /* Returns the absolute value of x: |x|. These convenience abs overloads are exclusive of C++. In C, abs is only declared in <cstdlib> (and operates on int values). The additional overloads are provided in this header (<cmath>) for the integral types: These overloads effectively cast x to a double before calculations (defined for T being any integral type). */
Really???
I have been bitten by this when porting a program to a new platform, since different compilers and standard libraries implementation differ here.
Here is my sample program:
#include <iostream> //#include <stdlib.h>//Necessary inclusion compil under linux //You can include either cmath or math.h, the result is the same //#include <cmath> #include <math.h> int main(int argc, const char * argv[]) { double x = -1.5; double ax = std::abs(x); std::cout << "x=" << x << " ax=" << ax << std::endl; return 0; }
And here is the result under MSVC 2010:
stdlib.h
: it seems like math.h
and stdlib.h
are always included whatever you dox=-1.5 ax=1.5
(seemingly correct according to the reference)Now here is the result under OSX:
-Wall
flag (the double to int cast is not signaled)! The result is the same if you replace g++
by llvm-g++
. The inclusion of math.h
or cmath
is not required for the compilation.x=-1.5 ax=1
And finally the result under Linux:
stdlib.h
is not included (at last, one compiler that does not include stdlib
automatically). No compilation warning is emitted for the double -> int cast.x=-1.5 ax=1
No clear winner here. I know that an obvious answer is "prefer std::abs
to ::abs
", but I wonder:
abs
should automatically provide double version outside of the std
namespace?math.h
silently)?std::abs(float), std::fabs, std::fabsf, std::fabsl. 1-8) Computes the absolute value of a floating point value arg .
The abs() function in C++ returns the absolute value of an integer number. This function is defined in the cstdlib header file. Mathematically, abs(num) = |num| .
The abs() function in C++ returns the absolute value of the argument. It is defined in the cmath header file. Mathematically, abs(num) = |num| .
Python | fabs() vs abs() Both will return the absolute value of a number. The difference is that math. fabs(number) will always return a floating-point number even if the argument is an integer, whereas abs() will return a floating-point or an integer depending upon the argument.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With