2012-08-28 29 views
5

Loại dữ liệu đôi không thể đại diện chính xác một số giá trị cơ sở 10. Điều này là do các số dấu phẩy động thể hiện số thực. Điều này có nghĩa là khi biểu diễn các giá trị tiền tệ, ta nên sử dụng kiểu giá trị thập phân để ngăn chặn lỗi. (cảm thấy tự do sửa lỗi trong phần mở đầu này)Giá trị nào không thể được biểu diễn chính xác bằng một đôi

Điều tôi muốn biết là các giá trị trình bày vấn đề như thế nào trong kiểu dữ liệu Đôi theo kiến ​​trúc 64 bit trong khung .Net chuẩn (C# nếu đó tạo nên sự khác biệt) ?

Tôi hy vọng câu trả lời là công thức hoặc quy tắc để tìm các giá trị như vậy nhưng tôi cũng muốn một số giá trị mẫu.

+0

Sử dụng số thập phân khi biểu diễn các giá trị tiền tệ - điều đó đúng ... và phải được theo dõi xem có trên vòm 64 bit hoặc 32 bit hay không. – JonH

+0

Hoặc cent (hoặc subcents) như là một BigInteger :) – Joey

+0

Như để xác định. Net, kiến ​​trúc 64, vv trong trường hợp có bất kỳ chi tiết thực hiện đã được đưa vào tài khoản để trả lời câu hỏi của tôi. – Gilles

Trả lời

7

Bất kỳ số nào không thể được viết dưới dạng tổng tích lũy và âm của 2 không thể được biểu diễn chính xác dưới dạng số dấu phẩy động nhị phân.

Phổ biến IEEE formats for 32- và 64-bit biểu diễn các số dấu phẩy động áp đặt thêm các ràng buộc; chúng giới hạn số lượng chữ số nhị phân trong cả hai định nghĩa và số mũ. Vì vậy, có số đại diện tối đa và tối thiểu (khoảng +/- 10^308 (cơ sở-10) nếu bộ nhớ phục vụ) và giới hạn độ chính xác của một số có thể được biểu diễn. Giới hạn về độ chính xác có nghĩa là, đối với số 64 bit, sự khác biệt giữa số mũ lũy thừa của công suất lớn nhất là 2 và công suất nhỏ nhất trong một số được giới hạn ở 52, vì vậy nếu số của bạn bao gồm một cụm từ trong 2^52 nó có thể cũng không bao gồm một thuật ngữ trong 2^-1.

Ví dụ đơn giản về các số không thể được biểu diễn chính xác trong các số dấu phẩy động nhị phân bao gồm 1/3, 2/3, 1/5.

Vì tập hợp các số dấu phẩy động (trong bất kỳ biểu diễn nào) là hữu hạn và tập hợp số thực là vô hạn, một thuật toán để tìm số thực không chính xác có thể biểu thị dưới dạng số dấu phẩy động một số thực ngẫu nhiên. Xác suất rằng số thực chính xác có thể biểu diễn dưới dạng số dấu phẩy động là 0.

+1

Trong khi '10^5000' không thể được biểu diễn bằng' double', có thể được biểu diễn chính xác dưới dạng số nhị phân dấu phẩy động. – CodesInChaos

1

Câu hỏi này thực sự vượt ra ngoài bất kỳ ngôn ngữ lập trình hoặc nền tảng duy nhất nào. Sự thiếu chính xác thực sự vốn có trong dữ liệu nhị phân.

Hãy xem xét rằng với một đôi, mỗi số N ở bên trái (tại chỉ số 0 dựa trên I) của dấu thập phân đại diện cho giá trị N * 2^I và mọi chữ số ở bên phải dấu thập phân đại diện cho giá trị N * 2^(- I).

Ví dụ: 5.625 (cơ sở 10) sẽ là 101.101 (cơ sở 2).

Với tính toán này và giá trị thập phân không thể được tính bằng tổng 2^(- I) cho các giá trị khác nhau của tôi sẽ có giá trị không chính xác làm giá trị kép.

+1

Điều này chỉ đặt ra câu hỏi. Làm cách nào để biết liệu một giá trị thập phân 10 cụ thể có thể được biểu diễn bằng N * 2^-i cho một số hữu hạn không? – Servy

+0

@Servy: http://cs.furman.edu/digitaldomain/more/ch6/dec_frac_to_bin.htm và nhiều tài liệu tham khảo khác trả lời câu hỏi của bạn. –

+1

@HighPerformanceMark Sau đó, bạn nên bao gồm điều đó trong câu trả lời của mình. Nếu không có nó, bạn không thực sự giúp anh ta giải quyết một vấn đề, bạn chỉ cần cho anh ta một vấn đề mới để giải quyết. – Servy

1

Bạn thường cần được chuẩn bị cho khả năng rằng bất kỳ giá trị nào bạn lưu trữ trong số double có một số lượng lỗi nhỏ. Trừ khi bạn đang lưu trữ một giá trị không đổi, rất có thể là nó có thể là một cái gì đó với ít nhất một số lỗi. Nếu điều bắt buộc là không bao giờ có bất kỳ lỗi nào và các giá trị không phải là hằng số, có thể bạn không nên sử dụng loại dấu phẩy động.

Điều bạn có thể nên hỏi trong nhiều trường hợp là "Làm cách nào để xử lý các lỗi dấu phẩy động nhỏ?" Bạn sẽ muốn biết loại hoạt động nào có thể dẫn đến nhiều lỗi và loại nào không. Bạn sẽ muốn đảm bảo rằng so sánh hai giá trị cho "bình đẳng" thực sự chỉ đảm bảo chúng "đủ gần" thay vì chính xác như nhau, v.v.

+0

Tại sao điều này lại bị giảm giá - không có gì sai về nó? – JonH

+0

@JonH Tôi hơi tò mò một chút. Tôi cho rằng về mặt kỹ thuật tôi đã không trả lời câu hỏi, tôi đã cố gắng giải quyết vấn đề gốc bất kể câu hỏi thực tế được hỏi. – Servy

+0

Nhưng câu trả lời của bạn sẽ giúp trả lời câu hỏi, tôi sẽ upvote nó nhưng tôi lo sợ đây là một số loại trả thù, không có gì sai về tuyên bố của bạn. – JonH

1

Một float được biểu diễn dưới dạng s, em trong công thức sau

s * m * 2^e 

Điều này có nghĩa rằng bất kỳ con số đó không thể được biểu diễn bằng cách sử dụng biểu thức đã cho (và trong các lĩnh vực tương ứng của s, em) không thể được biểu diễn chính xác.

Về cơ bản, bạn có thể đại diện cho tất cả các số giữa 02^53 - 1 nhân với một sức mạnh nhất định là hai (có thể là điện âm).

Ví dụ: tất cả các số giữa 02^53 - 1 có thể được biểu diễn nhân với 2^0 = 1. Và bạn cũng có thể đại diện cho tất cả những con số đó bằng cách chia chúng cho số 2 (với số phần là .5). Và cứ thế.

Câu trả lời này không bao gồm đầy đủ chủ đề, nhưng tôi hy vọng điều đó sẽ hữu ích.

Các vấn đề liên quan