Mengubah pelampung menjadi string tanpa membulatkannya

88

Saya membuat program yang, untuk alasan yang tidak perlu dijelaskan, membutuhkan float untuk diubah menjadi string untuk dihitung dengan len (). Namun, str (float (x)) menghasilkan x yang dibulatkan ketika diubah menjadi string, yang membuang semuanya. Apakah ada yang tahu cara memperbaikinya? Berikut kode yang digunakan jika Anda ingin tahu:

len(str(float(x)/3))
Galileo
sumber
2
jika x aslinya adalah str, kenapa di cast?
Vinko Vrsalovic
1
-1: Tidak ada contoh keluaran yang diperlukan untuk nilai yang berbeda x. Tanpa contoh, kita hanya bisa menebak apa masalahnya.
S. Lott

Jawaban:

128

Beberapa bentuk pembulatan seringkali tidak dapat dihindari saat berhadapan dengan bilangan floating point. Ini karena angka yang dapat Anda ekspresikan dengan tepat di basis 10 tidak selalu dapat diekspresikan dengan tepat di basis 2 (yang digunakan komputer Anda).

Sebagai contoh:

>>> .1
0.10000000000000001

Dalam kasus ini, Anda melihat .1 diubah menjadi string menggunakan repr:

>>> repr(.1)
'0.10000000000000001'

Saya percaya python memotong beberapa digit terakhir saat Anda menggunakan str () untuk mengatasi masalah ini, tetapi ini adalah solusi parsial yang tidak menggantikan pemahaman apa yang terjadi.

>>> str(.1)
'0.1'

Saya tidak yakin apa masalah "pembulatan" yang menyebabkan Anda. Mungkin Anda akan melakukannya lebih baik dengan pemformatan string sebagai cara untuk mengontrol output Anda dengan lebih tepat?

misalnya

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

Dokumentasi di sini .

John Fouhy
sumber
12
len(repr(float(x)/3))

Namun saya harus mengatakan bahwa ini tidak dapat diandalkan seperti yang Anda pikirkan.

Float dimasukkan / ditampilkan sebagai angka desimal, tetapi komputer Anda (pada kenyataannya, library C standar Anda) menyimpannya sebagai biner. Anda mendapatkan beberapa efek samping dari transisi ini:

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

Penjelasan tentang mengapa ini terjadi ada di bab tutorial python ini.

Solusinya adalah dengan menggunakan jenis yang secara khusus melacak angka desimal, seperti python decimal.Decimal:

>>> print len(str(decimal.Decimal('0.1')))
3
nosklo.dll
sumber
Posting bagus tentang cara bekerja dengan hasil float dari divisi: stackoverflow.com/questions/2958684/python-division
Trutane
3

Jawaban lain sudah menunjukkan bahwa representasi bilangan mengambang adalah masalah yang pelik.

Karena Anda tidak memberikan konteks yang cukup dalam pertanyaan Anda, saya tidak dapat mengetahui apakah modul desimal dapat berguna untuk kebutuhan Anda:

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

Di antara hal-hal lain Anda dapat secara eksplisit menentukan presisi yang ingin Anda peroleh (dari dokumen):

>>> 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')

Contoh sederhana dari prompt saya (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

Mungkin ini bisa membantu? desimal ada di python stdlib sejak 2.4, dengan tambahan di python 2.6.

Semoga ini bisa membantu, Francesco

Francesco
sumber
0

Saya tahu ini sudah terlambat tetapi bagi mereka yang baru pertama kali datang ke sini, saya ingin memposting solusi. Saya memiliki nilai float indexdan string imgfiledan saya memiliki masalah yang sama seperti Anda. Beginilah cara saya memperbaiki masalah tersebut

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

Outputnya adalah

1.0,data/2.jpg

Anda dapat mengubah contoh pemformatan ini sesuai kenyamanan Anda.

Harsh Wardhan
sumber