Konstanta NaN C / C ++ (literal)?

110

Apakah ini mungkin untuk menetapkan a NaNke doubleatau floatdi C / C ++? Seperti di JavaScript Anda lakukan: a = NaN. Jadi nanti Anda dapat memeriksa apakah variabel itu angka atau tidak.

exebook
sumber
Di sini saya menunjukkan bagaimana berbagai NaN terlihat ketika dibuat dengan cara yang berbeda: stackoverflow.com/questions/18118408/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Jawaban:

153

Dalam C, NANdideklarasikan dalam<math.h> .

Dalam C ++, std::numeric_limits<double>::quiet_NaN()dideklarasikan dalam <limits>.

Namun untuk memeriksa apakah suatu nilai adalah NaN, Anda tidak dapat membandingkannya dengan nilai NaN lainnya. Sebagai gantinya gunakan isnan()dari <math.h>dalam C, atau std::isnan()dari <cmath>dalam C ++.

Mike Seymour
sumber
20
Atau Anda dapat membandingkan angkanya dengan dirinya sendiri - x == xmengembalikan falseiff xadalah NaN.
Archie
7
@Archie: Saya rasa itu tidak dijamin dalam kedua bahasa.
Mike Seymour
3
@MikeSeymour Bukan dengan standar bahasa tetapi sejauh yang saya tahu itu harus berfungsi jika kompilator mengklaim mematuhi IEEE.
Pixelchemist
37
@Pixelchemist: Memang, ini adalah opsi jika Anda memerlukan kebingungan tetapi bukan portabilitas. Secara pribadi, saya lebih suka portabilitas tanpa kebingungan, jadi saya tidak akan menyarankannya sendiri.
Mike Seymour
9
catatan kecil: NAN adalah float, bukan double. link
orion elenzil
23

Seperti yang ditunjukkan orang lain, Anda mencari std::numeric_limits<double>::quiet_NaN()meskipun saya harus mengatakan saya lebih suka dokumen cppreference.com . Terutama karena pernyataan ini agak kabur:

Hanya berarti jika std :: numeric_limits :: has_quiet_NaN == true.

dan mudah untuk mengetahui apa artinya ini di situs ini, jika Anda memeriksa bagian mereka di std::numeric_limits::has_quiet_NaNsitu tertulis:

Konstanta ini bermakna untuk semua tipe floating-point dan dijamin benar jika std :: numeric_limits :: is_iec559 == true.

yang seperti yang dijelaskan di sini jika trueberarti platform Anda mendukung IEEE 754standar. Ini thread sebelumnya menjelaskan ini harus berlaku untuk kebanyakan situasi.

Shafik Yaghmour
sumber
9

Ini dapat dilakukan menggunakan numeric_limits di C ++:

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

Ini adalah metode yang mungkin ingin Anda lihat:

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.
bahasa
sumber
6
+1. Wikipedia memiliki beberapa informasi tentang NaN yang tenang dan memberi sinyal NaN .
Drew Noakes
1

Apakah ini mungkin untuk menetapkan NaN ke double atau float di C ...?

Ya, karena C99, (C ++ 11) <math.h>menawarkan fungsi di bawah ini:

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

yang seperti strtod("NAN(n-char-sequence)",0)rekan mereka dan NANuntuk tugas.

// 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);

Contoh keluaran: (Tergantung implementasi)

(7ff8000000012345)
(fff000000006789a)
(7ff8000000000000)
chux - Kembalikan Monica
sumber
1
Apa perbedaan antara keluaran untuk string yang berbeda? Manakah yang harus kita gunakan dalam kode numerik biasa?
quant_dev