2009-08-23 9 views
60

Tôi đang tạo một chương trình, vì những lý do không cần giải thích, yêu cầu một phao được chuyển đổi thành một chuỗi được tính bằng len(). Tuy nhiên, các kết quả str (float (x)) trong x được làm tròn khi được chuyển đổi thành một chuỗi, điều này làm giảm toàn bộ điều đó. Có ai biết sửa chữa nó không? Dưới đây là đoạn mã được sử dụng nếu bạn muốn biết:Chuyển đổi một phao sang một chuỗi mà không làm tròn nó

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

nếu x ban đầu là str, tại sao lại truyền? –

+1

-1: Không có ví dụ đầu ra yêu cầu cho các giá trị khác nhau của 'x'. Không có ví dụ, chúng tôi chỉ có thể đoán được vấn đề là gì. –

Trả lời

92

Một số hình thức làm tròn là thường không thể tránh khỏi khi giao dịch với số dấu chấm động. Điều này là do các số mà bạn có thể thể hiện chính xác trong cơ sở 10 không phải lúc nào cũng được thể hiện chính xác trong cơ số 2 (mà máy tính của bạn sử dụng).

Ví dụ:

>>> .1 
0.10000000000000001 

Trong trường hợp này, bạn đang thấy .1 chuyển thành một chuỗi sử dụng repr:

>>> repr(.1) 
'0.10000000000000001' 

Tôi tin rằng sườn python tắt vài chữ số cuối cùng khi bạn sử dụng str() để làm việc xung quanh vấn đề này, nhưng đó là một cách giải quyết một phần không thay thế cho sự hiểu biết những gì đang xảy ra.

>>> str(.1) 
'0.1' 

Tôi không chắc chắn chính xác vấn đề "làm tròn" đang gây ra cho bạn. Có lẽ bạn sẽ làm tốt hơn với định dạng chuỗi như là một cách để kiểm soát chính xác hơn đầu ra của bạn?

ví dụ:

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

Documentation here.

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

Tuy nhiên tôi phải nói rằng đây không phải là đáng tin cậy như bạn nghĩ.

Nổi được nhập/hiển thị dưới dạng số thập phân, nhưng máy tính của bạn (trên thực tế, thư viện C chuẩn của bạn) lưu trữ chúng dưới dạng nhị phân. Bạn nhận được một số tác dụng phụ từ quá trình chuyển đổi này:

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

Giải thích tại sao điều này xảy ra ở this chapter của hướng dẫn python.

Một giải pháp sẽ được sử dụng một loại mà cụ thể theo dõi số thập phân, như trăn của decimal.Decimal:

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

+1 cho số thập phân. –

+0

Bài đăng tốt về cách làm việc với kết quả nổi từ bộ phận: https://stackoverflow.com/questions/2958684/python-division – Trutane

3

Các câu trả lời khác đã chỉ ra rằng việc trình bày các số thực là một vấn đề hóc búa, để nói rằng ít nhất.

Vì bạn không cung cấp đủ bối cảnh trong câu hỏi của bạn, tôi không thể biết nếu module thập phân có thể hữu ích cho nhu cầu của bạn:

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

Trong số những thứ khác mà bạn có thể xác định một cách rõ ràng chính xác mà bạn muốn lấy (từ tài liệu):

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

Ví dụ đơn giản từ lời nhắc của tôi (trăn 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 

Có thể điều này có thể hữu ích? số thập phân nằm trong python stdlib kể từ 2.4, với phần bổ sung trong python 2.6.

Hy vọng điều này sẽ giúp, Francesco