您的位置:首页 > 编程语言 > Python开发

Python - abs vs fabs

2016-01-14 14:09 507 查看
abs(-5)


Second
import math
math.fabs(-5)


How do these methods differ?

python
shareimprove
this question
edited Feb
22 '14 at 16:46




Paul Draper
22.6k1156111

asked May 27 '12 at 7:16





Mateusz Jagiełło
89521426

add
a comment


3 Answers

activeoldestvotes

up vote59down
voteaccepted
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/alexei/<ipython-input-12-8368761369da> in <module>()
----> 1 type(math.fabs(3+4j))

TypeError: can't convert complex to float


shareimprove
this answer
edited Sep
19 '15 at 17:47




jesterjunk
1,059811

answered May 27 '12 at 7:21




NPE
225k29470666

2
abs
works
with far more than just integers and floats, and the result type is not always the same as the argument, e.g.
abs(3+4j)
. – agf May
27 '12 at 7:24
1
add in a comment about
fabs
taking
longer due to its always-float nature and you've got the right answer! – Patrick
Perini May
27 '12 at 7:25
@agf: Thanks for reminding me about complex numbers. Out of interest, what other classes of things can
__builtin__.abs()
be
successfully applied to? – NPE May
27 '12 at 7:31
2
@aix Any user defined class that defines the
__abs__
magic
method – agf May
27 '12 at 17:59
add
a comment





up vote4down
vote
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()
.

shareimprove
this answer
edited Nov
12 '13 at 0:33

answered May 27 '12 at 7:22




Kay Zhu
12.8k34162

3
You're not comparing apples to apples there. Use
from
math import fabs
for sure, and try
-5.0
for
both. – agf May
27 '12 at 7:25
@agf Thanks for pointing it out! That was dumb of me. – Kay
Zhu May
27 '12 at 7:31
Also unreliable timing results? You first had abs(-5) at 102ns, then later show it as 88.3ns. Never draw conclusions
from a single run of any benchmark, even if it internally tries to avoid the issues as timeit does. – Peter
Hansen Jan
3 '13 at 2:11
Two more points: this still compares apples and oranges, since abs is looked up in the builtins, while fabs is at module
namespace. Do "xabs = abs" then xabs(num) to remove that effect. Also, with Python 3.2 things change quite a bit and apparently abs() is quite a bit faster (>2x), at least on floats. – Peter
Hansen Jan
3 '13 at 2:14
@PeterHansen You are right, those are from two runs under different system loads. Though when compared within the same
set of tests, the relative difference is still valid. Also, thanks for pointing out the namespace difference -- I didn't consider that. I haven't tried it on 3.2, but that's good to know! I will update my answer with your suggestions a bit later :) Thanks
again! – Kay Zhu Jan
3 '13 at 2:20
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: