math.fabs() converts its argument to float if it can (if it can't, it throws an exception). It then takes the absolute value, and returns the result as a float.
In addition to floats, abs() also works with integers and complex numbers. Its return type depends on the type of its argument.
In [7]: type(abs(-2))
Out[7]: int
In [8]: type(abs(-2.0))
Out[8]: float
In [9]: type(abs(3+4j))
Out[9]: float
In [10]: type(math.fabs(-2))
Out[10]: float
In [11]: type(math.fabs(-2.0))
Out[11]: float
In [12]: type(math.fabs(3+4j))
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/home/npe/<ipython-input-12-8368761369da> in <module>()
----> 1 type(math.fabs(3+4j))
TypeError: can't convert complex to float
Edit: as @aix suggested, a better (more fair) way to compare the speed difference:
In [1]: %timeit abs(5)
10000000 loops, best of 3: 86.5 ns per loop
In [2]: from math import fabs
In [3]: %timeit fabs(5)
10000000 loops, best of 3: 115 ns per loop
In [4]: %timeit abs(-5)
10000000 loops, best of 3: 88.3 ns per loop
In [5]: %timeit fabs(-5)
10000000 loops, best of 3: 114 ns per loop
In [6]: %timeit abs(5.0)
10000000 loops, best of 3: 92.5 ns per loop
In [7]: %timeit fabs(5.0)
10000000 loops, best of 3: 93.2 ns per loop
In [8]: %timeit abs(-5.0)
10000000 loops, best of 3: 91.8 ns per loop
In [9]: %timeit fabs(-5.0)
10000000 loops, best of 3: 91 ns per loop
So it seems abs() only has slight speed advantage over fabs() for integers. For floats, abs() and fabs() demonstrate similar speed.
In addition to what @aix has said, one more thing to consider is the speed difference:
In [1]: %timeit abs(-5)
10000000 loops, best of 3: 102 ns per loop
In [2]: import math
In [3]: %timeit math.fabs(-5)
10000000 loops, best of 3: 194 ns per loop
So abs() is faster than math.fabs().
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++.)
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.
From an email response from Tim Peters:
Why does math have an fabs function? Both it and the abs builtin function wind up calling fabs() for floats. abs() is faster to boot.
Nothing deep -- the math module supplies everything in C89's standard libm (+ a few extensions), fabs() is a std C89 libm function.
There isn't a clear (to me) reason why one would be faster than the other; sounds accidental; math.fabs() could certainly be made faster (as currently implemented (via math_1), it endures a pile of general-purpose "try to guess whether libm should have set errno" boilerplate that's wasted (there are no domain or range errors possible for fabs())).
It seems there is no advantageous reason to use fabs. Just use abs for virtually all purposes.
i personally had an issue with my gcc compiler in c++ , when using abs it returns always an integer and not a double even if the result is a double , it was really a big issue for me at that time because it did not occur to me that abs could be a problem (i mean it is not obvious and easy to think that way). but i tried accidently using fabs and the issue is solved , now my program runs perfectly .