2012-05-27 23 views
87

me di cuenta de que en Python existen dos métodos de aspecto similar para encontrar el valor absoluto de un número:Python - ABS vs FABS

Primera

abs(-5) 

Segunda

import math 
math.fabs(-5) 

Cómo hacer estos métodos difieren?

Respuesta

109

math.fabs() convierte su argumento en flotante si puede (si no puede, arroja una excepción). Luego toma el valor absoluto y devuelve el resultado como un flotador.

Además de flotadores, abs() también funciona con números enteros y complejos. Su tipo de devolución depende del tipo de su argumento.

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 
+3

'abs' funciona con mucho más que enteros y flotantes, y el tipo de resultado es __not__ siempre el mismo que el argumento, ej. 'ABS (3 + 4j)'. – agf

+1

¡agregue un comentario sobre 'fabs' tardando más debido a su naturaleza siempre flotante y usted tiene la respuesta correcta! –

+0

@agf: Gracias por recordarme acerca de los números complejos. de interés, ¿qué otras clases de cosas pueden '__builtin __. ab s() 'ser aplicado con éxito a? – NPE

1

math.fabs() siempre devuelve flotador, mientras abs() puede devolver número entero.

+6

' abs' puede devolver cualquier tipo, dependiendo del método especial '__abs__' del tipo al que está llamado. – agf

8

Editar: @aix como sugirió, una manera mejor (más justa) para comparar la diferencia de velocidad:

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 

Así que parece abs() solamente tiene ligera ventaja de velocidad sobre fabs() para enteros. Para flotadores, abs() y fabs() demuestran una velocidad similar.


Además de lo @aix ha dicho, una cosa más a tener en cuenta es la diferencia de velocidad:

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 

Así abs() es más rápido que math.fabs().

+3

No está comparando manzanas con manzanas allí. Use 'from fabs de importación matemática' con seguridad, e intente' -5.0' para ambos. – agf

+0

@agf ¡Gracias por señalarlo! Eso fue tonto de mi parte –

+0

¿También resultados de tiempo poco confiables? Primero tuvo abs (-5) a 102ns, luego lo mostró como 88.3ns. Nunca saque conclusiones de una sola ejecución de cualquier punto de referencia, incluso si internamente trata de evitar los problemas a medida que transcurre el tiempo. –

0

abs(): Devuelve el valor absoluto según el argumento, es decir, si el argumento es int, entonces devuelve int, si el argumento es flotante, devuelve float. También funciona en variable compleja también, es decir, abs(a+bj) también funciona y devuelve valor absoluto es decir, "Math.sqrt (((a) ** 2) + ((b) ** 2)"

math.abs(): sólo funciona en los valores enteros o flotantes. Siempre devuelve el valor flotante absoluto sin importar cuál sea el tipo de argumento.