NAN có phù hợp để thông báo rằng một tham số không hợp lệ có liên quan đến phép tính không?


9

Tôi hiện đang làm việc trên một hệ thống xử lý số sẽ được triển khai trong môi trường quan trọng về hiệu năng. Nó lấy các đầu vào dưới dạng các mảng số (chúng sử dụng eigenthư viện, nhưng với mục đích của câu hỏi này có lẽ là phi vật chất) và thực hiện một số tính toán số (sản phẩm ma trận, nối, v.v.) để tạo đầu ra.

Tất cả các mảng được phân bổ tĩnh và kích thước của chúng được biết tại thời điểm biên dịch. Tuy nhiên, một số đầu vào thể không hợp lệ. Trong những trường hợp đặc biệt này , chúng tôi vẫn muốn mã được tính toán và chúng tôi vẫn muốn đầu ra không bị "ô nhiễm" bởi các giá trị không hợp lệ được sử dụng.

Để đưa ra một ví dụ, hãy lấy ví dụ tầm thường sau đây (đây là mã giả):

Matrix a = {1, 2, NAN, 4}; // this is the "input" matrix
Scalar b = 2;
Matrix output = b * a; // this results in {2, 4, NAN, 8}

Ý tưởng ở đây là 2, 4 và 8 là các giá trị có thể sử dụng được, nhưng NAN cần báo hiệu cho người nhận dữ liệu mà mục nhập đó có liên quan đến một hoạt động liên quan đến giá trị không hợp lệ và cần được loại bỏ (điều này sẽ được phát hiện qua std::isfinite(value)kiểm tra trước khi giá trị được sử dụng).

Đây có phải là một cách hợp lý để truyền đạt và truyền bá các giá trị không sử dụng được không, cho rằng hiệu suất là rất quan trọng và phân bổ heap không phải là một lựa chọn (và cả các cấu trúc tiêu tốn tài nguyên khác như boost::optionalhoặc con trỏ)?

Có cách nào tốt hơn để làm điều này? Tại thời điểm này, tôi khá hài lòng với thiết lập hiện tại nhưng tôi hy vọng sẽ nhận được một số ý tưởng mới hoặc phê bình hiệu quả về việc triển khai hiện tại.


6
IMHO đây chỉ là một trường hợp sử dụng hoàn hảo cho một NAN không có tín hiệu.
david.pfx

Câu trả lời:


8

Đây là một cách hoàn toàn hợp lý để đi. Cũng lưu ý rằng có nhiều mặt nạ bit được hiểu là NaN. Có hai loại NaN chính: báo hiệu (có thể đưa ra một ngoại lệ khi chúng được tạo, tùy thuộc vào cài đặt của bạn) và yên tĩnh (điều này không bao giờ thực hiện). Tuy nhiên, ngay cả trong NaN yên tĩnh, vẫn có nhiều mặt nạ bit tương ứng với NaN yên tĩnh. Nếu bạn muốn thực sự hiểu về nó, bạn có thể tạo NaN của riêng bạn khác với NaN thông thường. Chẳng hạn, bạn có thể sử dụng một mẫu bit cụ thể tương ứng với NA (là một khái niệm khác với NaN).

Đối với quan điểm của bạn về ô nhiễm. Điều này trở nên khó khăn hơn nhiều. Nói chung, bất kỳ hoạt động toán học liên quan đến NaN đều dẫn đến NaN. Nói cách khác, NaN dễ lây lan. Trong một số trường hợp, đây là những gì bạn muốn. Trong những người khác, nó không phải là. Chẳng hạn, giả sử bạn được hỏi về giá trị trung bình của vectơ bạn đã cho. Đó là NaN, hay 7/3? Tuy nhiên, sản phẩm vectơ vô hướng mà bạn đã cung cấp sẽ hoạt động chính xác theo cách bạn muốn và bạn cũng không cần thực hiện bất kỳ std::isfinitekiểm tra nào. Chỉ cần nhân số và NaN bật ra tự động, vì vậy nó khá hiệu quả. Tuy nhiên, nếu bạn muốn lấy trung bình 7/3 cho vectơ của mình, bạn cần khéo léo hơn, bởi vì làm điều đó một cách ngây thơ sẽ dẫn đến NaN. Mặc dù tôi không thể cho bạn biết cách thực hiện nhanh việc này, numpy có một và nguồn mở của nó, vì vậy bạn có thể xem xét điều đó.


1

Âm thanh của tôi tốt miễn là bạn đã sửa mô hình dấu phẩy động của mình và bạn đã nói về ngữ nghĩa NaN.

IEEE 754 là đủ trong trường hợp của bạn.

http://en.m.wikipedia.org/wiki/Single-precision_floating-point_format

/programming/5777484/how-to-check-if-c-compiler-uses-ieee-754-floating-point-st Chuẩn


2
bạn có muốn mở rộng một chút về những gì mỗi tài nguyên này có và tại sao bạn lại đề xuất những tài nguyên này khi trả lời câu hỏi không? "Câu trả lời chỉ liên kết" không được chào đón tại Stack Exchange
gnat
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.