Python'da neredeyse eşitlik için şamandıraları karşılaştırmanın en iyi yolu nedir?


332

Şamandıraların eşitlik için karşılaştırılmasının, yuvarlama ve hassasiyet sorunları nedeniyle biraz hareketsiz olduğu iyi bilinmektedir.

Örneğin: https://randomascii.wordpress.com/2012/02/25/karşılaştırma- yüzer- nokta- sayıları2012-tr/

Python'da bununla başa çıkmak için önerilen yol nedir?

Elbette bunun için bir yerde standart bir kütüphane işlevi var mı?


@tolomea: Uygulamanıza, verilerinize ve sorun alanınıza bağlı olduğundan - ve yalnızca bir kod satırı olduğundan - neden "standart kütüphane işlevi" olsun?
S.Lott

9
S.Lott @: all, any, max, minher temelde tek gömlekleri vardır ve bunlar sadece bir kütüphanede verilmez, bunlar fonksiyonları yerleşik konum. Yani BDFL'nin sebepleri bu değil. Çoğu insanın yazdığı bir kod satırı oldukça karmaşık değildir ve genellikle işe yaramaz, bu da daha iyi bir şey sağlamak için güçlü bir nedendir. Elbette başka stratejiler sunan herhangi bir modülün uygun olduklarını ve daha önemlisi uygun olmadıklarını açıklayan uyarılar sağlaması gerekir. Sayısal analiz zordur, dil tasarımcılarının genellikle ona yardımcı olacak araçlar denememesi büyük bir utanç değildir.
Steve Jessop

@Steve Jessop. Bu toplama odaklı işlevler, kayan noktaya uygulanan uygulama, veri ve sorun etki alanı bağımlılıklarına sahip değildir. Yani "tek astar" açıkça gerçek nedenler kadar önemli değil. Sayısal analiz zordur ve genel amaçlı bir dil kütüphanesinin birinci sınıf bir parçası olamaz.
S.Lott

6
@ S.Lott: Standart Python dağıtımının XML arabirimleri için birden fazla modülle gelip gelmediğini kabul ediyorum . Açıkçası, farklı uygulamaların farklı bir şey yapması gerektiği gerçeği, modülleri tabana öyle ya da böyle yapmak için sete koymak için hiç de bar değildir. Kuşkusuz çok fazla kullanılan şamandıraları karşılaştırmak için hileler var, en temel olanı belirtilen sayıda ulp. Bu yüzden sadece kısmen katılıyorum - sorun, sayısal analizin zor olması. Python olabilir prensipte biraz zaman biraz daha kolay hale getirmek için araçlar sağlar. Sanırım kimse gönüllü olmadı.
Steve Jessop

4
Ayrıca, "tasarım zor bir kod satırına kadar kaynar" - eğer düzgün bir kez yaptıktan sonra hala bir astar ise, monitörünüz benimkinden daha geniş olduğunu düşünüyorum ;-). Her neyse, bence tüm alan oldukça uzmanlaşmış, çoğu programcı (ben dahil) çok nadiren kullanıyor. Zor olmakla birlikte, çoğu dilde çekirdek kütüphaneler için "en çok arananlar" listesinin başına gelmeyecek.
Steve Jessop

Yanıtlar:


325

Python 3.5 , PEP 485'te açıklandığı gibi ekler math.iscloseve cmath.iscloseçalışır .

Python'un önceki bir sürümünü kullanıyorsanız, eşdeğer işlev belgelerde verilmiştir .

def isclose(a, b, rel_tol=1e-09, abs_tol=0.0):
    return abs(a-b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)

rel_tolgöreceli bir hoşgörüdür, iki argümanın büyüklüğünün büyüklüğüyle çarpılır; değerler büyüdükçe, aralarında izin verilen fark hala eşit olarak kabul edilir.

abs_tolher durumda olduğu gibi uygulanan mutlak bir toleranstır. Fark bu toleranslardan herhangi birinden azsa, değerler eşit kabul edilir.


26
ne zaman not aveya bbir olduğunu numpy array, numpy.iscloseeserlerini.
dbliss

6
@marsh rel_tolbir olan nispi tolerans , iki bağımsız değişken büyüklüklerinin daha büyük ile çarpılır; değerler büyüdükçe, aralarında izin verilen fark hala eşit olarak kabul edilir. abs_tolBir olan mutlak toleransı her durumda olduğu gibi uygulanır. Fark bu toleranslardan herhangi birinden azsa, değerler eşit kabul edilir.
Mark Ransom

5
Diğer bir deyişle "Modulo hata denetimi, vb fonksiyonu ... sonucunu döndürür",: Bu yanıt (Ben iyi bir tanesi düşünüyorum), dokümantasyon da diyor belirterek 's değerinde değerini azaltmak için değil iscloseişlevi (yukarıda) tam bir uygulama değildir .
rkersh

5
Eski bir konuyu canlandırmaktan dolayı özür dileriz, ancak iscloseher zaman daha az muhafazakar kritere uyduğunu belirtmeye değer görünüyordu . Sadece bundan bahsediyorum çünkü bu davranış bana mantıksız. İki kriter belirtecek olsaydım, her zaman küçük toleransın daha büyük olanın üstesinden gelmesini beklerdim.
Mackie Messer

3
@MackieMesser, elbette görüşüne hak kazanıyorsunuz, ancak bu davranış benim için çok mantıklıydı. Tanımınıza göre hiçbir şey sıfıra "yakın" olamazdı, çünkü sıfıra eşit bir sıfırlama her zaman sıfırdır.
Mark Ransom

72

Aşağıdaki kadar basit bir şey yeterince iyi değil mi?

return abs(f1 - f2) <= allowed_error

8
Verdiğim bağlantının işaret ettiği gibi, çıkarma yalnızca sayıların yaklaşık büyüklüğünü önceden biliyorsanız çalışır.
Gordon Wrigley

8
Tecrübelerime göre, şamandıralar karşılaştırmak için en iyi yöntemdir: abs(f1-f2) < tol*max(abs(f1),abs(f2)). Bu tür göreceli tolerans, genellikle küçük ondalık basamaklardaki yuvarlama hatasından etkilendikleri için şamandıraları genel olarak karşılaştırmanın tek anlamlı yoludur.
Sesquipedal

2
Neden işe yaramayabileceğine dair basit bir örnek ekleyerek:, >>> abs(0.04 - 0.03) <= 0.01verir False. Ben kullanımPython 2.7.10 [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Schatten

3
@schatten dürüst olmak gerekirse, bu örneğin makine ikili hassasiyeti / formatları ile ilgili karşılaştırma algodan daha fazla ilgisi vardır. Sisteme 0.03 girdiğinizde, bu gerçekten CPU'ya yapılan sayı değil.
Andrew White

2
@AndrewWhite bu örnek, abs(f1 - f2) <= allowed_errorbeklendiği gibi çalışmadığını gösterir .
Schatten

45

Gareth'in cevabının muhtemelen hafif bir fonksiyon / çözüm olarak en uygun olduğunu kabul ediyorum.

Ama NumPy kullanıyorsanız veya bunu düşünüyorsanız, bunun için paketlenmiş bir fonksiyon olduğunu not etmek yararlı olacağını düşündüm.

numpy.isclose(a, b, rtol=1e-05, atol=1e-08, equal_nan=False)

Yine de küçük bir sorumluluk reddi: NumPy'yi kurmak, platformunuza bağlı olarak önemsiz bir deneyim olabilir.


1
"Numpy'yi kurmak, platformunuza bağlı olarak önemsiz bir deneyim olabilir." ... um Ne? Hangi platformları numpy kurmak "önemsiz değil"? Tam olarak önemsiz olmayan nedir?
John

10
@John: Windows için 64 bit ikili almak zor. pipWindows üzerinden numpy almak zor .
Ben Bolker

@Ternak: Yapıyorum, ancak bazı öğrencilerim Windows kullanıyor, bu yüzden bu şeylerle uğraşmak zorundayım.
Ben Bolker

4
@BenBolker Python tarafından desteklenen açık veri bilimi platformunu kurmanız gerekiyorsa, en iyi yol Anaconda continuum.io/downloads (pandalar, numpy ve kutudan daha fazlası)
jrovegno

Anaconda takma önemsiz
Endolit

13

Sınıfı decimalsağlayan Python modülünü kullanın Decimal.

Yorumlardan:

Eğer matematik ağırlıklı bir iş yapıyorsanız ve ondalıktan kesinlikle kesinlike ihtiyacınız yoksa, bu gerçekten işleri başlatabilir. Şamandıralar, başa çıkmak için çok daha hızlı, ancak kesin değil. Ondalık sayılar son derece hassas ancak yavaştır.


11

Python standart kütüphanesinde (veya başka bir yerde) Dawson'un AlmostEqual2sComplementişlevini uygulayan hiçbir şeyin farkında değilim . İstediğiniz davranış bu ise, bunu kendiniz uygulamanız gerekir. (Bu durumda, Dawson'un akıllı bitsel kesmek kullanmak yerine, muhtemelen formun if abs(a-b) <= eps1*(abs(a)+abs(b)) + eps2veya benzerlerinin daha geleneksel testlerini kullanmak daha iyi olur . Dawson benzeri davranışlar elde etmek if abs(a-b) <= eps*max(EPS,abs(a),abs(b))için bazı küçük sabitler için böyle bir şey söyleyebilirsiniz EPS; Dawson ile aynı, ama ruh olarak benzer.


Burada ne yaptığınızı tam olarak takip etmiyorum, ama ilginç. Eps, eps1, eps2 ve EPS arasındaki fark nedir?
Gordon Wrigley

eps1ve eps2göreceli ve mutlak bir hoşgörü tanımlayın: izin verme ave ne kadar büyük olduklarını byaklaşık olarak farklılık göstermeye hazırsınız . tek bir toleranstır; ne kadar büyük olduklarına izin vermeye ve ne kadar büyük olduklarına göre farklılık göstermeye hazırsınız , ancak büyüklük veya daha küçük her şeyin boyut olarak kabul edilmesi gerekir . Kayan nokta türünüzün en küçük denormal olmayan değeri olarak alırsanız , bu, Dawson'un karşılaştırıcısına çok benzer (2 ^ # bit faktörü hariç, çünkü Dawson ulps cinsinden toleransı ölçer). eps1eps2epsabepsEPSEPSEPS
Gareth McCaughan

2
Bu arada, S. Lott ile Right Thing'in her zaman gerçek uygulamanıza bağlı olacağını kabul ediyorum, bu yüzden tüm kayan nokta karşılaştırma ihtiyaçlarınız için tek bir standart kütüphane işlevi yoktur.
Gareth McCaughan

@ gareth-mccaughan Python için "kayan nokta tipinizin en küçük denormal olmayan değeri" nasıl belirlenir?
Gordon Wrigley

Bu sayfa docs.python.org/tutorial/floatingpoint.html , neredeyse tüm python uygulamalarının IEEE-754 çift kesinlikli şamandıralar kullandığını ve bu sayfanın en.wikipedia.org/wiki/IEEE_754-1985 sıfıra en yakın normalleştirilmiş sayıların ± 2 * olduğunu söylüyor * -1022.
Gordon Wrigley

11

Kayan nokta sayılarının eşitlik için karşılaştırılamayacağı konusundaki ortak akıl yanlıştır. Kayan noktalı sayılar tamsayılardan farklı değildir: Eğer "a == b" değerini değerlendirirseniz, aynı sayılar ve yanlışsa, doğru olur (iki NaN'nin elbette aynı sayılar olmadığı anlaşılır).

Asıl sorun şudur: Bazı hesaplamalar yaptım ve karşılaştırmam gereken iki sayının tam olarak doğru olduğundan emin değilseniz, o zaman ne? Bu sorun kayan nokta için tamsayılarla aynıdır. "7/3 * 3" tamsayı ifadesini değerlendirirseniz, "7 * 3/3" ile eşit karşılaştırılmaz.

Diyelim ki "Tamsayı eşitlik için nasıl karşılaştırırım?" böyle bir durumda. Tek bir cevap yok; ne yapmanız gerektiği belirli duruma, özellikle ne tür hatalara ve ne elde etmek istediğinize bağlıdır.

İşte bazı olası seçenekler.

Eğer matematiksel olarak kesin sayılar eşit olursa "doğru" bir sonuç elde etmek istiyorsanız, iki sayıda aynı hataları aldığınızı kanıtlamak için yaptığınız hesaplamaların özelliklerini kullanmaya çalışabilirsiniz. Bu uygulanabilirse ve tam olarak hesaplanırsa eşit sayılar verecek ifadelerden kaynaklanan iki sayıyı karşılaştırırsanız, karşılaştırmadan "true" alırsınız. Başka bir yaklaşım, hesaplamaların özelliklerini analiz edebilmeniz ve hatanın hiçbir zaman belirli bir miktarı, belki de mutlak bir miktarı veya girdilerden birine veya çıktılardan birine göre bir miktarı aşmadığını kanıtlayabilmenizdir. Bu durumda, hesaplanan iki sayının en fazla bu miktarda farklılık gösterip göstermediğini sorabilir ve aralık dahilindeyse "true" değerini döndürebilirsiniz. Bağlı bir hatayı kanıtlayamıyorsanız, tahmin edebilir ve en iyisini umabilirsiniz. Tahmin etmenin bir yolu, birçok rastgele örneği değerlendirmek ve sonuçlarda ne tür bir dağılım elde ettiğinizi görmektir.

Tabii ki, sadece matematiksel olarak kesin sonuçlar eşitse "true" alma gereksinimini ayarladığımız için, eşit olmasa bile "true" alma olasılığını açık bıraktık. (Aslında, her zaman "doğru" döndürerek gereksinimi karşılayabiliriz. Bu hesaplamayı basitleştirir, ancak genellikle istenmeyen bir durumdur, bu yüzden aşağıdaki durumu iyileştirmeyi tartışacağım.)

Eğer matematiksel olarak kesin sayılar eşit değilse "yanlış" bir sonuç elde etmek istiyorsanız, matematiksel olarak tam sayılar eşit değilse sayıları değerlendirmenizin farklı sayılar verdiğini kanıtlamanız gerekir. Bu, birçok yaygın durumda pratik amaçlar için imkansız olabilir. Öyleyse bir alternatif düşünelim.

Matematiksel olarak kesin sayılar belirli bir miktardan daha fazla farklılık gösteriyorsa, yararlı bir gereklilik "yanlış" sonuç almamız olabilir. Örneğin, belki de bir bilgisayar oyununda atılan topun nereye gittiğini hesaplayacağız ve yarasa vurup vurmadığını bilmek istiyoruz. Bu durumda, top sopayı vurursa kesinlikle "doğru" almak istiyoruz ve top sopayı çok uzaktaysa "yanlış" almak istiyoruz ve eğer top matematiksel olarak kesin bir simülasyon yarasayı kaçırdı, ancak yarasa vurmanın milimetresi içinde. Bu durumda, topun pozisyonu ve yarasa pozisyonu hesaplamamızda en fazla bir milimetre (ilgili tüm pozisyonlar için) birleşik hata olduğunu kanıtlamamız (veya tahmin / tahmin etmemiz) gerekir. Bu bize her zaman geri dönmemizi sağlar "

Bu nedenle, kayan nokta sayılarını karşılaştırırken neye geri döneceğinize nasıl karar vereceğiniz çok özel durumunuza bağlıdır.

Hesaplamalar için hata sınırlarını nasıl kanıtlayacağınız konusunda, bu karmaşık bir konu olabilir. En yakın yuvarlak modda IEEE 754 standardını kullanan herhangi bir kayan nokta uygulaması, herhangi bir temel işlem için kesin sonuca en yakın kayan nokta sayısını döndürür (özellikle çarpma, bölme, toplama, çıkarma, kare kök). (Beraberlik durumunda, düşük bitin eşit olması için yuvarlak yapın.) (Karekök ve bölünme konusunda özellikle dikkatli olun; dil uygulamanız IEEE 754'e uygun olmayan yöntemler kullanabilir.) Bu gereksinim nedeniyle, tek bir sonuçtaki hata, en az anlamlı bit değerinin en fazla 1 / 2'sidir. (Daha fazla olsaydı, yuvarlama değerin 1 / 2'si dahilinde farklı bir sayıya giderdi.)

Oradan devam etmek oldukça karmaşıklaşıyor; bir sonraki adım, girişlerden birinin zaten bir hata yaptığı bir işlem gerçekleştirmektir. Basit ifadeler için, bu hatalar son hatada bir sınıra ulaşmak için hesaplamalar yoluyla takip edilebilir. Uygulamada, bu yalnızca yüksek kaliteli bir matematik kütüphanesinde çalışmak gibi birkaç durumda yapılır. Ve elbette, tam olarak hangi işlemlerin gerçekleştirileceği üzerinde kesin kontrole ihtiyacınız var. Üst düzey diller genellikle derleyiciye bol bol gevşeklik sağlar, bu nedenle hangi sipariş işlemlerinin gerçekleştirildiğini bilmiyor olabilirsiniz.

Bu konu hakkında yazılabilecek (ve yazılabilecek) çok daha fazlası var, ama orada durmam gerekiyor. Özet olarak, cevap: Bu karşılaştırma için kütüphane rutini yoktur, çünkü bir kütüphane rutininin içine koymaya değer en ihtiyaçlara uyan tek bir çözüm yoktur. (Göreceli veya mutlak bir hata aralığıyla karşılaştırmak sizin için yeterliyse, bunu bir kütüphane rutini olmadan yapabilirsiniz.)


3
Yukarıdaki Gareth McCaughan ile yapılan tartışmadan, göreceli bir hatayla doğru bir şekilde karşılaştırmak aslında "abs (ab) <= eps max (2 * -1022, abs (a), abs (b))" anlamına gelir, bu tarif ettiğim bir şey değil basit ve kesinlikle kendi başıma çalıştığım bir şey değil. Ayrıca Steve Jessop'un belirttiği gibi, hepsi yerleşik olan max, min, any ve all ile benzer karmaşıklığa sahiptir. Bu nedenle, standart matematik modülünde göreceli bir hata karşılaştırması sağlamak iyi bir fikir gibi görünüyor.
Gordon Wrigley

(7/3 * 3 == 7 * 3/3) python'da True değerini değerlendirir.
xApple

@ xApple: OS X 10.8.3 üzerinde Python 2.7.2'yi çalıştırdım ve girdim (7/3*3 == 7*3/3). Yazdırdı False.
Eric Postpischil

3
Muhtemelen yazmayı unuttun from __future__ import division. Bunu yapmazsanız, kayan nokta sayısı yoktur ve karşılaştırma iki tamsayı arasındadır.
xApple

3
Bu önemli bir tartışma, ama inanılmaz derecede yararlı değil.
Dan Hulme

6

Test / TDD bağlamında kullanmak istiyorsanız, bunun standart bir yol olduğunu söyleyebilirim:

from nose.tools import assert_almost_equals

assert_almost_equals(x, y, places=7) #default is 7

5

math.isclose () bunun için Python 3.5'e eklenmiştir ( kaynak kodu ). İşte Python 2'ye bir bağlantı noktası. Mark Ransom'un bir astarından farkı, "inf" ve "-inf" yi düzgün bir şekilde işleyebilmesidir.

def isclose(a, b, rel_tol=1e-09, abs_tol=0.0):
    '''
    Python 2 implementation of Python 3.5 math.isclose()
    https://hg.python.org/cpython/file/tip/Modules/mathmodule.c#l1993
    '''
    # sanity check on the inputs
    if rel_tol < 0 or abs_tol < 0:
        raise ValueError("tolerances must be non-negative")

    # short circuit exact equality -- needed to catch two infinities of
    # the same sign. And perhaps speeds things up a bit sometimes.
    if a == b:
        return True

    # This catches the case of two infinities of opposite sign, or
    # one infinity and one finite number. Two infinities of opposite
    # sign would otherwise have an infinite relative tolerance.
    # Two infinities of the same sign are caught by the equality check
    # above.
    if math.isinf(a) or math.isinf(b):
        return False

    # now do the regular computation
    # this is essentially the "weak" test from the Boost library
    diff = math.fabs(b - a)
    result = (((diff <= math.fabs(rel_tol * b)) or
               (diff <= math.fabs(rel_tol * a))) or
              (diff <= abs_tol))
    return result

2

Aşağıdaki karşılaştırmayı yararlı buldum:

str(f1) == str(f2)

ilginç, ancak str (.1 + .2) == .3
Gordon Wrigley'den

str (.1 + .2) == str (.3) True
değerini

Bu, f1 == f2'den nasıl farklıdır - ikisi de yakın olsa da hassasiyet nedeniyle hala farklıysa, dize gösterimleri de eşit olmaz.
MrMas

2
.1 + .2 == .3 False değerini döndürürken str (.1 + .2) == str (.3) True
değerini

4
Python 3.7.2'de str(.1 + .2) == str(.3)False değerini döndürür. Yukarıda açıklanan yöntem sadece Python 2 için geçerlidir.
Danibix

1

Kaynak numarası gösterimini etkileyebileceğiniz bazı durumlarda, tamsayı payı ve payda kullanarak bunları kayan yerine kesir olarak gösterebilirsiniz. Bu şekilde tam karşılaştırmalar yapabilirsiniz.

Ayrıntılar için Kesirler modülünden kesir bölümüne bakın .


1

@Sesquipedal'ın önerisini beğendim ama değişiklikle (her iki değer 0 olduğunda özel bir kullanım durumu False döndürür). Benim durumumda Python 2.7'deydim ve sadece basit bir işlev kullandım:

if f1 ==0 and f2 == 0:
    return True
else:
    return abs(f1-f2) < tol*max(abs(f1),abs(f2))

1

2 sayının aynı 'hassasiyete kadar' olduğundan emin olmak istediğiniz durumda kullanışlıdır, toleransı belirtmeye gerek yoktur:

  • 2 sayının minimum hassasiyetini bulun

  • Her ikisini de minimum hassasiyete yuvarlayın ve karşılaştırın

def isclose(a,b):                                       
    astr=str(a)                                         
    aprec=len(astr.split('.')[1]) if '.' in astr else 0 
    bstr=str(b)                                         
    bprec=len(bstr.split('.')[1]) if '.' in bstr else 0 
    prec=min(aprec,bprec)                                      
    return round(a,prec)==round(b,prec)                               

Yazıldığı gibi, yalnızca dize temsillerinde 'e' olmayan sayılar için çalışır (yani 0.9999999999995e-4 <sayı <= 0.9999999999995e11)

Misal:

>>> isclose(10.0,10.049)
True
>>> isclose(10.0,10.05)
False

Sınırsız kapanış kavramı size iyi hizmet etmeyecektir. isclose(1.0, 1.1)üretir Falseve isclose(0.1, 0.000000000001)geri döner True.
kfsone

1

Belirli bir ondalık sayıya kadar karşılaştırma yapmak için atol/rtol:

def almost_equal(a, b, decimal=6):
    return '{0:.{1}f}'.format(a, decimal) == '{0:.{1}f}'.format(b, decimal)

print(almost_equal(0.0, 0.0001, decimal=5)) # False
print(almost_equal(0.0, 0.0001, decimal=4)) # True 

1

Bu belki biraz çirkin bir hack'tir, ancak varsayılan şamandıra hassasiyetinden (yaklaşık 11 ondalık) daha fazlasına ihtiyacınız olmadığında oldukça iyi çalışır.

Round_to fonksiyonu kullanan biçimi yöntemi yerleşik sonra gerekli ondalık sayısı ile şamandırayı temsil eder ve bir dizeye şamandıra yuvarlamak str sınıf geçerlidir gelen eval yerleşik fonksiyonu geri almak için yuvarlak şamandıra dizeye kayan sayı türüne.

İs_close fonksiyon sadece yuvarlak yukarı şamandıra için basit koşullu uygular.

def round_to(float_num, prec):
    return eval("'{:." + str(int(prec)) + "f}'.format(" + str(float_num) + ")")

def is_close(float_a, float_b, prec):
    if round_to(float_a, prec) == round_to(float_b, prec):
        return True
    return False

>>>a = 10.0
10.0
>>>b = 10.0001
10.0001
>>>print is_close(a, b, prec=3)
True
>>>print is_close(a, b, prec=4)
False

Güncelleme:

@Stepehjfox tarafından önerildiği gibi, "eval" den kaçınarak bir rount_to işlevi oluşturmanın daha temiz bir yolu iç içe biçimlendirmeyi kullanmaktır :

def round_to(float_num, prec):
    return '{:.{precision}f}'.format(float_num, precision=prec)

Aynı fikri izleyerek, yeni harika f-stringleri (Python 3.6+) kullanarak kod daha da basit olabilir :

def round_to(float_num, prec):
    return f'{float_num:.{prec}f}'

Böylece, hepsini tek bir basit ve temiz 'is_close' işlevinde toplayabiliriz :

def is_close(a, b, prec):
    return f'{a:.{prec}f}' == f'{b:.{prec}f}'

1
eval()Parametreli biçimlendirme için kullanmak zorunda değilsiniz . Gibi bir şey return '{:.{precision}f'.format(float_num, precision=decimal_precision) yapmalı
stephenjfox


1
Teşekkürler @stephenjfox İç içe biçimlendirmeyi bilmiyordum. Btw, örnek kodunuz biten kıvırcık parantezlerden yoksun:return '{:.{precision}}f'.format(float_num, precision=decimal_precision)
Albert Alomar

1
İyi yakalama ve özellikle f-stringleri ile iyi yapılmış geliştirme. Köşedeki Python 2'nin ölümü ile, belki de bu norm haline gelecek
stephenjfox

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.