Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

NaN ใน C++ คืออะไร? การจัดการค่าที่ไม่ใช่ตัวเลข

NaN (Not a Number) เป็นค่าเฉพาะในระบบ Floating-Point (IEEE 754) ที่แทนผลลัพธ์ของการดำเนินการทางคณิตศาสตร์ที่ "ไม่ได้ถูกกำหนด" หรือ "ไม่สามารถแสดงเป็นตัวเลขได้" ใน C++ NaN เป็นส่วนหนึ่งของ float, double, และ long double

สถานการณ์ที่เกิด NaN

  • รากที่สองของจำนวนลบ: sqrt(-5)
  • การหารศูนย์ด้วยศูนย์: 0.0 / 0.0
  • การดำเนินการกับ Infinity: INF - INF, INF * 0
  • ฟังก์ชันตรีโกณมีติกที่นอกโดเมน: acos(2.0)

ตัวอย่างโค้ด

#include <iostream>
#include <cmath>
#include <limits>

using namespace std;

int main() {
    double result = sqrt(-5.0);
    cout << "Square root of -5: " << result << endl;
    // Output: Square root of -5: nan

    // ตรวจสอบ NaN
    if (isnan(result)) {
        cout << "Result is NaN!" << endl;
    }

    // สร้าง NaN โดยตรง
    double nan_val = numeric_limits<double>::quiet_NaN();
    cout << "Direct NaN: " << nan_val << endl;

    // NaN ไม่เท่ากับตัวมันเอง (คุณสมบัติเฉพาะ)
    cout << "NaN == NaN? " << (nan_val == nan_val) << endl; // false
    return 0;
}

คุณสมบัติสำคัญของ NaN

  1. NaN != NaN - การเปรียบเทียบ NaN กับตัวเองจะคืนค่า false เสมอ
  2. ใช้ std::isnan() (จาก <cmath>) เพื่อตรวจสอบแทนการเปรียบเทียบ
  3. มีสองประเภท: Quiet NaN (แพร่กระจายโดยไม่ยก Exception) และ Signaling NaN (ยก Exception)
  4. การดำเนินการใดๆ กับ NaN จะให้ผลลัพธ์เป็น NaN ต่อไป (Propagation)
  5. แนวทางปฏิบัติที่ดี (Best Practices)

    • ตรวจสอบ Input ก่อนเรียกฟังก์ชันคณิตศาสตร์ (เช่น if (x >= 0) sqrt(x))
    • ใช้ std::isnan() ตรวจสอบผลลัพธ์หลังการคำนวณที่อาจเกิด NaN
    • พิจารณาใช้ std::optional หรือ Error Handling แทนการคืนค่า NaN ใน API

    สรุป

    NaN เป็นกลไกมาตรฐานสำหรับจัดการข้อผิดพลาดทางคณิตศาสตร์ใน Floating-Point การเข้าใจพฤติกรรมของ NaN (โดยเฉพาะ NaN != NaN) จำเป็นสำหรับการเขียนโค้ดทางวิทยาศาสตร์/วิศวกรรมที่มั่นคงใน C++