Python - abs vs fabs

Mat*_*łło 101 python

我注意到在python中有两种类似的查找方法来查找数字的绝对值:

第一

abs(-5)
Run Code Online (Sandbox Code Playgroud)

第二

import math
math.fabs(-5)
Run Code Online (Sandbox Code Playgroud)

这些方法有何不同?

NPE*_*NPE 122

math.fabs()如果可以,将其参数转换为float(如果不能,则抛出异常).然后取绝对值,并将结果作为float返回.

除浮点数外,abs()还可以使用整数和复数.它的返回类型取决于其参数的类型.

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
Run Code Online (Sandbox Code Playgroud)

  • `abs`的工作原理不仅仅是整数和浮点数,结果类型__not__总是与参数相同,例如`abs(3 + 4j)`. (4认同)
  • @aix任何定义`__abs__`魔术方法的用户定义类 (4认同)

K Z*_*K Z 9

编辑:正如@a​​ix建议的那样,比较速度差异的更好(更公平)的方式:

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
Run Code Online (Sandbox Code Playgroud)

因此,对于整数而言似乎abs()只有轻微的速度优势fabs().对于花车,abs()fabs()表现出类似的速度.


除了@aix所说的,另外还要考虑的是速度差异:

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
Run Code Online (Sandbox Code Playgroud)

所以abs()快于math.fabs().

  • 你不是在那里比较苹果和苹果.使用`from math import fabs`肯定,并尝试`-5.0`. (3认同)
  • @PeterHansen 你是对的,它们来自不同系统负载下的两次运行。尽管在同一组测试中进行比较时,相对差异仍然有效。另外,感谢您指出命名空间的差异——我没有考虑到这一点。我还没有在 3.2 上尝试过,但很高兴知道!稍后我会用您的建议更新我的答案:) 再次感谢! (2认同)