การแปลงลอยเป็นสตริงโดยไม่ต้องปัดเศษ


88

ฉันกำลังทำโปรแกรมที่ด้วยเหตุผลที่ไม่จำเป็นต้องอธิบายต้องใช้ float เพื่อแปลงเป็นสตริงเพื่อนับด้วย len () อย่างไรก็ตาม str (float (x)) ส่งผลให้ x ถูกปัดเศษเมื่อแปลงเป็นสตริงซึ่งจะทำให้ทุกอย่างหลุดออกไป มีใครรู้วิธีแก้ไขหรือไม่? นี่คือรหัสที่ใช้หากคุณต้องการทราบ:

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

2
ถ้า x เดิมเป็น str ทำไมต้องแคส?
Vinko Vrsalovic

1
-1: ไม่มีตัวอย่างผลลัพธ์ที่ต้องการสำหรับค่าต่างๆของx. หากไม่มีตัวอย่างเราสามารถเดาได้ว่าปัญหาคืออะไร
ล็อต

คำตอบ:


128

การปัดเศษบางรูปแบบมักหลีกเลี่ยงไม่ได้เมื่อต้องจัดการกับตัวเลขทศนิยม เนื่องจากตัวเลขที่คุณสามารถแสดงได้อย่างแน่นอนในฐาน 10 นั้นไม่สามารถแสดงได้อย่างแน่นอนในฐาน 2 (ซึ่งคอมพิวเตอร์ของคุณใช้)

ตัวอย่างเช่น:

>>> .1
0.10000000000000001

ในกรณีนี้คุณจะเห็น. 1 แปลงเป็นสตริงโดยใช้repr:

>>> repr(.1)
'0.10000000000000001'

ฉันเชื่อว่า python ตัดตัวเลขสองสามตัวสุดท้ายออกเมื่อคุณใช้ str () เพื่อแก้ไขปัญหานี้ แต่เป็นวิธีแก้ปัญหาบางส่วนที่ไม่ได้ทดแทนความเข้าใจว่าเกิดอะไรขึ้น

>>> str(.1)
'0.1'

ฉันไม่แน่ใจว่า "การปัดเศษ" มีปัญหาอะไรกันแน่ บางทีคุณอาจทำได้ดีกว่าด้วยการจัดรูปแบบสตริงเพื่อเป็นวิธีในการควบคุมเอาต์พุตของคุณอย่างแม่นยำยิ่งขึ้น?

เช่น

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

เอกสารที่นี่ .


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

อย่างไรก็ตามฉันต้องบอกว่ามันไม่น่าเชื่อถืออย่างที่คุณคิด

การลอยตัวจะถูกป้อน / แสดงเป็นตัวเลขทศนิยม แต่คอมพิวเตอร์ของคุณ (อันที่จริงไลบรารี C มาตรฐานของคุณ) จะจัดเก็บเป็นเลขฐานสอง คุณได้รับผลข้างเคียงจากการเปลี่ยนแปลงนี้:

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

คำอธิบายว่าเหตุใดจึงเกิดขึ้นอยู่ในบทช่วยสอน Python นี้

วิธีแก้ปัญหาคือการใช้ประเภทที่ติดตามตัวเลขทศนิยมโดยเฉพาะเช่น python's decimal.Decimal:

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

โพสต์ดีๆเกี่ยวกับวิธีการทำงานกับผลลัพธ์ float จากการหาร: stackoverflow.com/questions/2958684/python-division
Trutane

3

คำตอบอื่น ๆ ได้ชี้ให้เห็นแล้วว่าการเป็นตัวแทนของตัวเลขลอยตัวเป็นปัญหาที่มีความเสี่ยง

เนื่องจากคุณให้บริบทไม่เพียงพอในคำถามของคุณฉันจึงไม่สามารถทราบได้ว่าโมดูลทศนิยมจะมีประโยชน์สำหรับความต้องการของคุณหรือไม่

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

เหนือสิ่งอื่นใดคุณสามารถระบุความแม่นยำที่คุณต้องการได้รับอย่างชัดเจน (จากเอกสาร):

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

ตัวอย่างง่ายๆจากพรอมต์ของฉัน (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

อาจจะช่วยได้? ทศนิยมอยู่ใน python stdlib ตั้งแต่ 2.4 โดยมีการเพิ่มใน python 2.6

หวังว่านี่จะช่วยได้ Francesco


0

ฉันรู้ว่ามันสายเกินไป แต่สำหรับผู้ที่มาที่นี่เป็นครั้งแรกฉันอยากจะโพสต์วิธีแก้ปัญหา ฉันมีค่าลอยตัวindexและสตริงimgfileและฉันก็มีปัญหาเช่นเดียวกับคุณ นี่คือวิธีที่ฉันแก้ไขปัญหา

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

ผลลัพธ์คือ

1.0,data/2.jpg

คุณสามารถแก้ไขตัวอย่างการจัดรูปแบบนี้ได้ตามความสะดวกของคุณ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.