Bir şamandırayı yuvarlamadan dizeye dönüştürme


88

Açıklanması gerekmeyen nedenlerle, bir float'ın len () ile sayılacak bir dizgeye dönüştürülmesini gerektiren bir program yapıyorum. Bununla birlikte, str (float (x)), x'in bir dizeye dönüştürüldüğünde yuvarlanmasıyla sonuçlanır, bu da tüm şeyi atar. Bunun için bir düzeltme bilen var mı? Bilmek istiyorsanız, işte kullanılan kod:

len(str(float(x)/3))

2
x başlangıçta str ise, neden oyuncu kadrosu?
Vinko Vrsalovic

1
-1: Farklı değerler için gerekli çıktıya örnek yok x. Örnekler olmadan, sorunun ne olduğunu sadece tahmin edebiliriz.
S.Lott

Yanıtlar:


128

Kayan noktalı sayılarla uğraşırken bir tür yuvarlama genellikle kaçınılmazdır. Bunun nedeni, tam olarak 10 tabanında ifade edebileceğiniz sayıların her zaman tam olarak 2 tabanında (bilgisayarınızın kullandığı) tam olarak ifade edilememesidir.

Örneğin:

>>> .1
0.10000000000000001

Bu durumda, .1'in aşağıdakileri kullanarak bir dizeye dönüştürüldüğünü görüyorsunuz repr:

>>> repr(.1)
'0.10000000000000001'

Bu soruna geçici bir çözüm bulmak için str () kullandığınızda python'un son birkaç basamağı keseceğine inanıyorum, ancak bu, neler olup bittiğini anlamanın yerine geçmeyen kısmi bir çözümdür.

>>> str(.1)
'0.1'

"Yuvarlamanın" size ne gibi sorunlara yol açtığından tam olarak emin değilim. Belki de çıktınızı daha hassas bir şekilde kontrol etmenin bir yolu olarak dize biçimlendirmeyi daha iyi yaparsınız?

Örneğin

>>> '%.5f' % .1
'0.10000'
>>> '%.5f' % .12345678
'0.12346'

Belgeler burada .


12
len(repr(float(x)/3))

Ancak bunun düşündüğünüz kadar güvenilir olmadığını söylemeliyim.

Kayan sayılar ondalık sayılar olarak girilir / görüntülenir, ancak bilgisayarınız (aslında standart C kitaplığınız) bunları ikili olarak depolar. Bu geçişten bazı yan etkiler yaşarsınız:

>>> print len(repr(0.1))
19
>>> print repr(0.1)
0.10000000000000001

Bunun neden olduğuna dair açıklama python öğreticisinin bu bölümünde yer almaktadır.

Python'unki gibi, ondalık sayıları özellikle izleyen bir tür kullanmak bir çözüm olabilir decimal.Decimal:

>>> print len(str(decimal.Decimal('0.1')))
3


3

Diğer cevaplar, kayan sayıların temsilinin en hafif tabirle çetrefilli bir konu olduğuna işaret etti.

Sorunuza yeterince bağlam vermediğinden, ondalık modülün ihtiyaçlarınız için yararlı olup olmayacağını bilemiyorum:

http://docs.python.org/library/decimal.html

Diğer şeylerin yanı sıra, elde etmek istediğiniz kesinliği açıkça belirtebilirsiniz (belgelerden):

>>> getcontext().prec = 6
>>> Decimal('3.0')
Decimal('3.0')
>>> Decimal('3.1415926535')
Decimal('3.1415926535')
>>> Decimal('3.1415926535') + Decimal('2.7182818285')
Decimal('5.85987')
>>> getcontext().rounding = ROUND_UP
>>> Decimal('3.1415926535') + Decimal('2.7182818285')
Decimal('5.85988')

Bilgi istemimden basit bir örnek (python 2.6):

>>> import decimal
>>> a = decimal.Decimal('10.000000001')
>>> a
Decimal('10.000000001')
>>> print a
10.000000001
>>> b = decimal.Decimal('10.00000000000000000000000000900000002')
>>> print b
10.00000000000000000000000000900000002
>>> print str(b)
10.00000000000000000000000000900000002
>>> len(str(b/decimal.Decimal('3.0')))
29

Belki bu yardımcı olabilir? ondalık, 2.4'ten beri python stdlib'de, python 2.6'da eklemelerle.

Umarım bu yardımcı olur, Francesco


0

Bunun çok geç olduğunu biliyorum ama buraya ilk kez gelenler için bir çözüm göndermek istiyorum. Bir float değerim indexve bir dizem var imgfileve sizinle aynı sorunu yaşadım. Sorunu bu şekilde çözdüm

index = 1.0
imgfile = 'data/2.jpg'
out = '%.1f,%s' % (index,imgfile)
print out

Çıktı

1.0,data/2.jpg

Bu biçimlendirme örneğini size kolaylık sağlayacak şekilde değiştirebilirsiniz.

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.