Sự khác biệt giữa các cách để so sánh số dấu phẩy động


7

Dường như có nhiều cách tiếp cận để đánh giá xem hai số dấu phẩy động có giống nhau hay không. Dưới đây là một số ví dụ tôi đã tìm thấy:

  1. fabs(x - y) < n * FLT_EPSILON * fabs(x) HOẶC LÀ fabs(x - y) < n * FLT_EPSILON * fabs(y)

  2. fabs(x - y) < n * FLT_EPSILON * fabs(x + y)

  3. fabs(x - y) < n * FLT_EPSILON * fabs(x + y) || fabs(x - y) < FLT_MIN)

  4. fabs(x - y) < n * FLT_EPSILON * sqrt(x * x + y * y + FLT_EPSILON * FLT_EPSILON)

Tôi thực sự bối rối về họ. Giả sử có một cách tốt nhất để so sánh hai số dấu phẩy động, đó là cách đơn giản nhất cũng như chính xác nhất, các cách tiếp cận khác thậm chí không tồn tại. Vì vậy, những cách khác nhau phải có ưu và nhược điểm riêng.

Câu hỏi của tôi là: Để thực hiện "tính toán thực sự", cách tiếp cận nào là chính xác nhất?


Liên kết tham khảo:

http://accu.org/index.php/journals/1558 (1 và 4)

https://stackoverflow.com/a/10335601/5399734 (2 và 3)


2
Thật không may, phân tích số không phải là một vấn đề nhỏ và sự lựa chọn chính xác có thể phụ thuộc vào loại tính toán mà bạn đang thực hiện.
Yuval Filmus

Câu trả lời:


2

Bạn đang nhầm lẫn chính xác, bởi vì những câu trả lời này trộn lẫn các khái niệm không tương thích thành một mớ hỗn độn.

Nếu bạn muốn biết hai số dấu phẩy động có bằng nhau hay không thì bạn sử dụng toán tử "==", nó sẽ cho bạn biết chính xác hoàn toàn cho dù chúng có bằng nhau hay không.

Nếu bạn muốn biết liệu chúng có giống nhau hay không, điều đó hơi khó hơn: Có +0 và -0 bằng nhau nhưng không giống nhau và có NaN (Không phải là số) không bằng nhau, thậm chí không bằng chính chúng , nhưng có thể giống hệt nhau.

Bây giờ nếu bạn thực hiện số học dấu phẩy động, thì có thể xảy ra rằng hai phép tính nên có cùng kết quả toán học sẽ cho kết quả khác nhau do lỗi làm tròn. Cũng có thể xảy ra rằng hai phép tính nên có kết quả toán học khác nhau sẽ cho cùng một kết quả.

Không có quy tắc nhanh chóng và dễ dàng . Bạn cần suy nghĩ về mục tiêu của bạn là gì và làm thế nào để đạt được nó. Và mỗi trường hợp là khác nhau.

Tái bút (4) chỉ là khủng khiếp. Hoàn toàn, sai hoàn toàn. Nếu bạn sử dụng độ chính xác kép và một trong x, y lớn hơn 10 ^ 160, thì gần như hai số bất kỳ sẽ được coi là "bằng" bởi mã này.

Tái bút (1-3) đều khủng khiếp như nhau, vì họ cho rằng 0 0.

Tái bút (3) là khủng khiếp - nó phá hủy hoàn toàn ý tưởng về dòng chảy dần dần.

Tái bút Theo quy định, bạn nên sử dụng độ chính xác kép thay vì độ chính xác đơn, trừ khi bạn có lý do rất chính đáng để không; một lý do mà bạn có thể giải thích và bảo vệ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.