C / C ++ NaN hằng số (theo nghĩa đen)?


110

Điều này có thể gán a NaNcho a doublehoặc floattrong C / C ++ không? Giống như trong JavaScript bạn làm: a = NaN. Vì vậy, sau này bạn có thể kiểm tra xem biến có phải là số hay không.


Ở đây tôi cho thấy các NaN khác nhau trông như thế nào khi được tạo bằng các phương tiện khác nhau: stackoverflow.com/questions/18118408/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Câu trả lời:


153

Trong C, NANđược khai báo trong <math.h>.

Trong C ++, std::numeric_limits<double>::quiet_NaN()được khai báo trong <limits>.

Nhưng để kiểm tra xem một giá trị có phải là NaN hay không, bạn không thể so sánh nó với một giá trị NaN khác. Thay vào đó, hãy sử dụng isnan()từ <math.h>trong C hoặc std::isnan()từ <cmath>trong C ++.


20
Hoặc bạn có thể so sánh số với chính nó - x == xtrả về falseiff xlà NaN.
Archie

7
@Archie: Tôi không nghĩ điều đó được đảm bảo bằng cả hai ngôn ngữ.
Mike Seymour

3
@MikeSeymour Không phải theo tiêu chuẩn ngôn ngữ nhưng theo tôi biết thì nó sẽ hoạt động nếu trình biên dịch tuyên bố là tuân thủ IEEE.
Pixelchemist

37
@Pixelchemist: Thật vậy, đó là một lựa chọn nếu bạn cần sự xáo trộn nhưng không phải tính di động. Cá nhân tôi thích tính di động mà không bị xáo trộn, vì vậy tôi sẽ không tự mình đề xuất.
Mike Seymour

9
lưu ý nhỏ: NAN là một phao, không phải là một kép. liên kết
orion elenzil

23

Như những người khác đã chỉ ra rằng bạn đang tìm kiếm std::numeric_limits<double>::quiet_NaN()mặc dù tôi phải nói rằng tôi thích các tài liệu cppreference.com hơn . Đặc biệt là vì tuyên bố này hơi mơ hồ:

Chỉ có ý nghĩa nếu std :: numeric_limits :: has_quiet_NaN == true.

và thật đơn giản để tìm ra ý nghĩa của điều này trên trang web này, nếu bạn kiểm tra phần của họ trên std::numeric_limits::has_quiet_NaNđó cho biết:

Hằng số này có ý nghĩa đối với tất cả các kiểu dấu phẩy động và được đảm bảo là đúng nếu std :: numeric_limits :: is_iec559 == true.

như được giải thích ở đây nếu truecó nghĩa là nền tảng của bạn hỗ trợ IEEE 754tiêu chuẩn. Đây thread trước giải thích điều này nên là đúng đối với hầu hết các tình huống.


9

Điều này có thể được thực hiện bằng cách sử dụng numeric_limits trong C ++:

http://www.cplusplus.com/reference/limits/numeric_limits/

Đây là những phương pháp bạn có thể muốn xem:

infinity()  T   Representation of positive infinity, if available.
quiet_NaN() T   Representation of quiet (non-signaling) "Not-a-Number", if available.
signaling_NaN() T   Representation of signaling "Not-a-Number", if available.

6
+1. Wikipedia có một số thông tin về NaN yên tĩnhbáo hiệu NaN .
Drew Noakes

1

Điều này có thể gán một NaN cho một double hoặc float trong C ... không?

Có, vì C99, (C ++ 11) <math.h>cung cấp các chức năng dưới đây:

#include <math.h>
double nan(const char *tagp);
float nanf(const char *tagp);
long double nanl(const char *tagp);

giống như strtod("NAN(n-char-sequence)",0)đối tác của họ và NANcho các bài tập.

// Sample C code
uint64_t u64;
double x;
x = nan("0x12345");
memcpy(&u64, &x, sizeof u64); printf("(%" PRIx64 ")\n", u64);
x = -strtod("NAN(6789A)",0);
memcpy(&u64, &x, sizeof u64); printf("(%" PRIx64 ")\n", u64);
x = NAN;
memcpy(&u64, &x, sizeof u64); printf("(%" PRIx64 ")\n", u64);

Đầu ra mẫu: (Tùy thuộc vào việc thực hiện)

(7ff8000000012345)
(fff000000006789a)
(7ff8000000000000)

1
Sự khác biệt giữa các đầu ra cho các chuỗi khác nhau là gì? Chúng ta nên sử dụng cái nào trong mã số điển hình?
quant_dev
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.