Python - abs vs fabs

abs(-5)

Second

import math
math.fabs(-5)

How do these methods differ?

share improve this question
 

3 Answers

up vote 59 down vote accepted

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
share improve this answer
 
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

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().

share improve this answer
 
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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值