ค่าคงที่ของ C / C ++ NaN (ตามตัวอักษร)?


110

เป็นไปได้ไหมที่จะกำหนด a NaNให้กับ a doubleหรือfloatใน C / C ++ เช่นเดียวกับใน JavaScript ที่คุณทำ: a = NaN. คุณสามารถตรวจสอบได้ในภายหลังว่าตัวแปรเป็นตัวเลขหรือไม่


ที่นี่ฉันจะแสดงให้เห็นว่า NaN ต่างๆมีลักษณะอย่างไรเมื่อสร้างขึ้นโดยวิธีต่างๆ: stackoverflow.com/questions/18118408/…
Ciro Santilli 郝海东冠状病六四事件法轮功

คำตอบ:


153

ใน C NANประกาศเป็น<math.h>.

ใน C ++ std::numeric_limits<double>::quiet_NaN()ถูกประกาศในรูปแบบ<limits>.

แต่สำหรับการตรวจสอบว่าค่าเป็น NaN คุณไม่สามารถเปรียบเทียบกับค่า NaN อื่นได้ แทนที่จะใช้isnan()จาก<math.h>ใน C หรือstd::isnan()จาก<cmath>ใน C ++


20
หรือคุณสามารถเปรียบเทียบตัวเลขกับตัวมันเอง - x == xส่งกลับfalseiff xคือ NaN
Archie

7
@ Archie: ฉันไม่คิดว่าจะรับประกันเป็นภาษาใดภาษาหนึ่ง
Mike Seymour

3
@MikeSeymour ไม่ใช่ตามมาตรฐานภาษา แต่เท่าที่ฉันรู้ว่าควรใช้งานได้หากคอมไพเลอร์อ้างว่าเป็นไปตามมาตรฐาน IEEE
Pixelchemist

39
@Pixelchemist: อันที่จริงมันเป็นตัวเลือกถ้าคุณต้องการความสับสน แต่ไม่สามารถพกพาได้ โดยส่วนตัวแล้วฉันชอบการพกพาที่ไม่มีความสับสนดังนั้นฉันจะไม่แนะนำด้วยตัวเอง
Mike Seymour

9
หมายเหตุรอง: แนนเป็นโฟลตไม่ใช่คู่ ลิงค์
orion elenzil

23

ตามที่คนอื่น ๆ ชี้ให้เห็นว่าคุณกำลังมองหาstd::numeric_limits<double>::quiet_NaN()แม้ว่าฉันต้องบอกว่าฉันชอบเอกสารcppreference.comมากกว่า โดยเฉพาะอย่างยิ่งเนื่องจากข้อความนี้คลุมเครือเล็กน้อย:

มีความหมายก็ต่อเมื่อ std :: numeric_limits :: has_quiet_NaN == true

และเป็นเรื่องง่ายที่จะเข้าใจว่าสิ่งนี้หมายถึงอะไรในไซต์นี้หากคุณตรวจสอบส่วนของพวกเขาในstd::numeric_limits::has_quiet_NaNนั้นระบุว่า:

ค่าคงที่นี้มีความหมายสำหรับประเภททศนิยมทั้งหมดและรับประกันว่าเป็นจริงถ้า std :: numeric_limits :: is_iec559 == จริง

ซึ่งตามที่อธิบายไว้ที่นี่หากtrueหมายความว่าแพลตฟอร์มของคุณรองรับIEEE 754มาตรฐาน นี้ด้ายก่อนหน้านี้อธิบายนี้ควรจะเป็นจริงสำหรับสถานการณ์ส่วนใหญ่


9

สามารถทำได้โดยใช้ numeric_limits ใน C ++:

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

นี่คือวิธีการที่คุณอาจต้องการดู:

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. วิกิพีเดียมีข้อมูลบางส่วนในที่เงียบสงบน่านและส่งสัญญาณน่าน
Drew Noakes

1

เป็นไปได้ไหมที่จะกำหนด NaN ให้เป็นสองเท่าหรือลอยใน C ...

ใช่ตั้งแต่ C99 (C ++ 11) <math.h>มีฟังก์ชันด้านล่าง:

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

ซึ่งเปรียบเสมือนเพื่อนร่วมงานstrtod("NAN(n-char-sequence)",0)และNANงานมอบหมาย

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

ผลลัพธ์ตัวอย่าง: (ขึ้นอยู่กับการใช้งาน)

(7ff8000000012345)
(fff000000006789a)
(7ff8000000000000)

1
อะไรคือความแตกต่างระหว่างเอาต์พุตสำหรับสตริงที่แตกต่างกัน? เราควรใช้รหัสใดในรหัสตัวเลขทั่วไป
quant_dev
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.