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

วิธีจับ Divide by Zero Error ใน C++ (Exception Handling)

ภาพรวม

ใน C++ การหารด้วยศูนย์ (Division by Zero) สำหรับ Integer Types เป็น Undefined Behavior (UB) โปรแกรมอาจ Crash, ให้ผลผิด, หรือทำงานต่อได้ (ขึ้นอยู่กับ Hardware/OS) สำหรับ Floating-Point จะได้ inf หรือ nan ตาม IEEE 754

วิธีป้องกัน: ตรวจสอบก่อนหาร (Pre-check) หรือใช้ Exception Handling (try/catch)

วิธีที่ 1: Pre-check (แนะนำ - เร็วที่สุด)


#include <iostream>
using namespace std;

double safeDivide(double numerator, double denominator) {
    if (denominator == 0.0) {
        throw runtime_error("Division by zero!");
    }
    return numerator / denominator;
}

int main() {
    double a = 10.0, b = 0.0;
    
    try {
        double result = safeDivide(a, b);
        cout << "Result: " << result << "\n";
    } catch (const exception& e) {
        cerr << "Error: " << e.what() << "\n";
    }
    
    return 0;
}

วิธีที่ 2: Integer Division with Custom Exception


#include <iostream>
#include <stdexcept>
using namespace std;

int intDivide(int numerator, int denominator) {
    if (denominator == 0) {
        throw invalid_argument("Division by zero: denominator cannot be zero");
    }
    return numerator / denominator;
}

int main() {
    int a = 10, b = 0;
    
    try {
        int result = intDivide(a, b);
        cout << "Result: " << result << "\n";
    } catch (const invalid_argument& e) {
        cerr << "Invalid Argument: " << e.what() << "\n";
    } catch (const exception& e) {
        cerr << "Other Error: " << e.what() << "\n";
    }
    
    return 0;
}

ผลลัพธ์


Error: Division by zero: denominator cannot be zero

Floating-Point Division by Zero (IEEE 754)


#include <iostream>
#include <cmath>  // isnan, isinf
#include <limits>
using namespace std;

int main() {
    double a = 10.0;
    double b = 0.0;
    
    double result = a / b;  // No Exception! Returns inf
    
    cout << "Result: " << result << "\n";           // inf
    cout << "Is INF: " << isinf(result) << "\n";    // 1 (true)
    cout << "Is NaN: " << isnan(result) << "\n";    // 0 (false)
    
    // 0.0 / 0.0 = NaN
    double nanResult = 0.0 / 0.0;
    cout << "0.0/0.0 = " << nanResult << "\n";      // nan
    cout << "Is NaN: " << isnan(nanResult) << "\n"; // 1 (true)
    
    return 0;
}

ผลลัพธ์ Floating-Point


Result: inf
Is INF: 1
Is NaN: 0
0.0/0.0 = nan
Is NaN: 1

Advanced: Structured Exception Handling (Windows SEH)

บน Windows สามารถจับ Hardware Exception (Integer Divide by Zero) ได้ด้วย SEH:


// Windows Only - Not Portable!
#include 
#include 

int main() {
    __try {
        int a = 10, b = 0;
        int c = a / b;  // Hardware Exception
    }
    __except (EXCEPTION_EXECUTE_HANDLER) {
        std::cout << "Caught Hardware Exception: Division by Zero\n";
    }
    return 0;
}

Best Practices

  1. Pre-check ก่อนหาร: if (denom != 0) result = num / denom; (Fastest, No Exception Overhead)
  2. ใช้ Exception สำหรับ Exceptional Cases: ไม่ใช่ Control Flow ปกติ
  3. Integer Division: ต้อง Check เอง (UB)
  4. Floating-Point: Check isinf(), isnan() หลังคำนวณ
  5. Custom Exception Class: สำหรับ Domain-Specific Errors

Custom Exception Class Example


#include 
#include 

class MathError : public std::runtime_error {
    int code_;
public:
    MathError(const std::string& msg, int code) 
        : std::runtime_error(msg), code_(code) {}
    int code() const { return code_; }
};

double divide(double a, double b) {
    if (b == 0.0) throw MathError("Division by zero", 1001);
    return a / b;
}

สรุป

TypeBehaviorHandling
Integer / 0Undefined Behavior (Crash/Garbage)Manual Check + Throw
Float / 0.0±infinity (IEEE 754)Check isinf()
0.0 / 0.0NaN (Not a Number)Check isnan()
Float / 0 (Integer 0)Promoted to Float → ±infinityCheck isinf()