ภาพรวม
ใน 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
- Pre-check ก่อนหาร:
if (denom != 0) result = num / denom;(Fastest, No Exception Overhead) - ใช้ Exception สำหรับ Exceptional Cases: ไม่ใช่ Control Flow ปกติ
- Integer Division: ต้อง Check เอง (UB)
- Floating-Point: Check
isinf(),isnan()หลังคำนวณ - 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;
}
สรุป
| Type | Behavior | Handling |
|---|---|---|
| Integer / 0 | Undefined Behavior (Crash/Garbage) | Manual Check + Throw |
| Float / 0.0 | ±infinity (IEEE 754) | Check isinf() |
| 0.0 / 0.0 | NaN (Not a Number) | Check isnan() |
| Float / 0 (Integer 0) | Promoted to Float → ±infinity | Check isinf() |