2013-01-02 65 views
8

thể trùng lặp:
Python rounding error with float numbers
python maths is wrongLỗi Python trong phép trừ cơ bản?

tôi không thể nhận Python để làm một cách chính xác các phép trừ 1-0,8 và gán nó. Nó tiếp tục với câu trả lời sai, 0.19999999999999996.

tôi khám phá một chút:

sq = {} 
sub = {} 
for i in range(1000): 
    sq[str(i/1000.)+'**2']=((i/1000.)**2) 
    sub['1-'+str(i/1000.)]=(1.0-(i/1000.)) 

và phát hiện ra rằng lỗi này xảy ra với một nhóm phần nào ngẫu nhiên của các phao nổi giữa 0 và 1 đến nơi thập phân thứ ba. Một lỗi tương tự cũng xảy ra khi bạn vuông những float đó, nhưng với một tập hợp con khác.

Tôi hy vọng giải thích về điều này và cách làm cho Python thực hiện quyền số học. Sử dụng round(x,3) là công việc hiện tại tôi đang sử dụng, nhưng nó không thanh lịch.

Cảm ơn!

Đây là một phiên trong Python 2.7.3 shell:

*** Python 2.7.3 (default, Apr 10 2012, 23:24:47) [MSC v.1500 64 bit (AMD64)] on win32. *** 
*** Remote Python engine is active *** 
>>> 1-0.8 
0.19999999999999996 
>>> print 1-0.8 
0.2 
>>> a = 1-0.8 
>>> a 
0.19999999999999996 
>>> print a 
0.2 
>>> a = 0.2 
>>> print a 
0.2 
>>> a 
0.2 
>>> 

Dưới đây là đoạn code tôi đưa vào một vài dịch viên trực tuyến:

def doit(): 
    d = {'a':1-0.8} 
    return d 

print doit() 

và đầu ra:

{'a': 0.19999999999999996} 
+3

séc http://www.yoda.arachsys.com/csharp/floatingpoint.html – avasal

+0

http://effbot.org/pyfaq/why-are -floating-point-calculate-so-inaccurate.htm –

Trả lời

8

Số thực không hoạt động như bạn mong đợi.

Để bắt đầu, hãy đọc floating point guide. Dài câu chuyện ngắn: máy tính đại diện cho số điểm nổi như nhị phân, và nó chỉ ra rằng lưu trữ một phần thập phân chính xác như nhị phân là không thể (try it for yourself trên giấy để xem lý do tại sao). Đối với mục đích thực tế, 0.19999999999999996 là "đủ gần" đến 0,2. Nếu bạn muốn in dưới dạng 0,2, thì bạn có thể làm điều gì đó như:

print "%0.1f" % floating_point_value 

Vì vậy, những gì bạn thấy không phải là lỗi. Đó là hành vi mong đợi.

+0

Cảm ơn. BTW, đầu ra của doit() là một từ điển, không phải là một số nguyên, do đó, 'in '% 0.1f"% doit() 'không hoạt động trong trường hợp này. – gotube

+0

Bạn chính xác. Tôi đã cập nhật câu trả lời để rõ ràng hơn một chút. – misha

1

Cửa hàng Python nổi với 'bit' và một số phao bạn không thể đại diện chính xác, cho dù bạn có bao nhiêu bit chính xác. Đây là vấn đề bạn có ở đây. Đó là sorta như cố gắng để viết 1/3 trong thập phân với một số lượng hạn chế của thập phân nơi hoàn toàn chính xác.

8

Sử dụng Decimal của nó được thiết kế chỉ cho việc này:

>>> from decimal import Decimal, getcontext 
>>> Decimal(1) - Decimal(0.8) 
Decimal('0.1999999999999999555910790150') 
>>> getcontext().prec = 3 
>>> Decimal(1) - Decimal(0.8) 
Decimal('0.200') 
>>> float(Decimal(1) - Decimal(0.8)) 
0.2 
Các vấn đề liên quan