Python - abs ve fabs


107

Python'da bir sayının mutlak değerini bulmak için iki benzer arama yöntemi olduğunu fark ettim:

İlk

abs(-5)

İkinci

import math
math.fabs(-5)

Bu yöntemler nasıl farklılık gösterir?

Yanıtlar:


127

math.fabs()eğer yapabiliyorsa argümanını float'a dönüştürür (yapamazsa, bir istisna atar). Daha sonra mutlak değeri alır ve sonucu bir kayan nokta olarak döndürür.

Yüzen abs()sayılara ek olarak tamsayılar ve karmaşık sayılarla da çalışır. Dönüş türü, argümanının türüne bağlıdır.

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

4
abstamsayılar ve kayan sayılardan çok daha fazlasıyla çalışır ve sonuç türü her zaman bağımsız değişkenle aynı değildir , örn abs(3+4j).
agf

1
fabsher zaman dalgalı yapısı nedeniyle daha uzun süre alma hakkında bir yorum ekleyin ve doğru cevabı aldınız!
Patrick Perini

@agf: Karmaşık sayıları hatırlattığın için teşekkürler. İlgi dışı, başka hangi tür şeylere __builtin__.abs()başarıyla uygulanabilir?
NPE

5
@aix __abs__Sihirli yöntemi tanımlayan herhangi bir kullanıcı tanımlı sınıf
agf

9

Düzenleme: @aix'in önerdiği gibi, hız farkını karşılaştırmanın daha iyi (daha adil) bir yolu:

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

Yani tam sayılara göre abs()sadece hafif bir hız avantajına sahip görünüyor fabs(). Şamandıralar için abs()ve fabs()benzer hızı gösterin.


@Aix'in söylediklerine ek olarak, dikkate alınması gereken bir şey daha hız farkıdır:

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

Yani abs()daha hızlı math.fabs().


3
Orada elmaları elmalarla karşılaştırmıyorsunuz. from math import fabsKesin kullanın ve -5.0ikisini de deneyin .
agf

Ayrıca güvenilmez zamanlama sonuçları mı? Önce 102ns'de abs (-5) vardı, sonra bunu 88.3ns olarak gösterdin. Zaman içinde sorunları dahili olarak önlemeye çalışsa bile, herhangi bir karşılaştırmalı değerlendirmenin tek bir çalışmasından asla sonuç çıkarmayın.
Peter Hansen

1
İki nokta daha: bu hala elmaları ve portakalları karşılaştırır, çünkü abs yerleşiklerde aranır, fabs ise modül ad alanında. Bu etkiyi kaldırmak için "xabs = abs" ve ardından xabs (num) yapın. Ayrıca, Python 3.2 ile işler biraz değişir ve görünüşe göre abs (), en azından float'larda biraz daha hızlıdır (> 2x).
Peter Hansen

1
@PeterHansen Haklısınız, bunlar farklı sistem yükleri altında iki çalışmadan. Aynı test seti içinde kıyaslandığında, göreceli fark hala geçerlidir. Ayrıca ad alanı farkına işaret ettiğiniz için teşekkürler - bunu dikkate almadım. 3.2'de denemedim ama bunu bilmek güzel! Cevabımı önerilerinizle biraz sonra güncelleyeceğim :) Tekrar teşekkürler!
KZ

3

math.fabs()her zaman float döndürür, abs()tamsayı döndürebilir.


6
abs__abs__çağrıldığı türün özel yöntemine bağlı olarak herhangi bir türü döndürebilir .
agf

0

abs(): Bağımsız değişkene göre mutlak değeri döndürür, yani bağımsız değişken int ise int, değişken float ise float döndürür. Ayrıca karmaşık değişken üzerinde de çalışır, yani abs(a+bj)mutlak değerde çalışır ve döndürür yanimath.sqrt(((a)**2)+((b)**2)

math.fabs(): Yalnızca tamsayı veya kayan değerlerde çalışır. Bağımsız değişken türü ne olursa olsun her zaman mutlak kayan değeri döndürür (karmaşık sayılar hariç).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.