Điều này thực sự không liên quan gì đến Python - bạn sẽ thấy cùng một hành vi trong bất kỳ ngôn ngữ nào bằng cách sử dụng số học dấu phẩy động nhị phân của phần cứng. Đầu tiên read the docs.
Sau khi bạn đọc điều đó, bạn sẽ hiểu rõ hơn rằng bạn đang không thêm một phần trăm trong mã của mình. Đây chính xác là những gì bạn đang thêm:
>>> from decimal import Decimal
>>> Decimal(.01)
Decimal('0.01000000000000000020816681711721685132943093776702880859375')
Chuỗi đó cho biết giá trị thập phân chính xác của giá trị nhị phân ("chính xác kép" trong C) xấp xỉ với giá trị thập phân chính xác 0,01. Thứ bạn đang thực sự thêm lớn hơn 1/100.
Kiểm soát lỗi số dấu phẩy động là trường được gọi là "phân tích số" và là một chủ đề rất lớn và phức tạp. Vì vậy, miễn là bạn đang giật mình bởi thực tế là phao chỉ là xấp xỉ giá trị thập phân, sử dụng mô-đun decimal
. Điều đó sẽ lấy đi một thế giới của những vấn đề "nông cạn" cho bạn. Ví dụ, do sự thay đổi nhỏ này để chức năng của bạn:
from decimal import Decimal as D
def sqrt(num):
root = D(0)
while root * root < num:
root += D("0.01")
return root
thì:
>>> sqrt(4)
Decimal('2.00')
>>> sqrt(9)
Decimal('3.00')
Nó không thực sự chính xác hơn, nhưng có thể ít ngạc nhiên trong các ví dụ đơn giản vì bây giờ nó thêm chính xác một một hàng trăm.
Cách khác là gắn vào phao nổi và thêm nội dung nào đó là chính xác thể hiện dưới dạng phao nhị phân: giá trị của biểu mẫu I/2**J
. Ví dụ: thay vì thêm 0,01, hãy thêm 0,125 (1/8) hoặc 0,0625 (1/16).
Sau đó tra cứu "phương pháp Newton" để tính căn bậc hai ;-)
Nguồn
2013-10-20 04:18:20
Có thể thử mô-đun [thập phân] (http://docs.python.org/2/library/decimal.html), là được thiết kế cho độ chính xác? – Michael0x2a