이번 글에서는 C 또는 C++에서 두 개의 float(부동 소수점) 값 또는 double 값을 비교하는 방법을 살펴보겠습니다. 부동 소수점 수의 비교는 정수 비교와 달리 단순한 등호 연산만으로는 정확한 결과를 얻기 어렵기 때문에 별도의 접근 방식이 필요합니다.
float나 double 값을 비교할 때는 반드시 정밀도(precision)를 함께 고려해야 합니다. 예를 들어 3.1428과 3.1415라는 두 수는 0.01 수준의 정밀도에서는 같은 값으로 볼 수 있지만, 0.001 수준에서 비교하면 서로 다른 값입니다.
따라서 이러한 기준으로 비교하려면 한 부동 소수점 수에서 다른 수를 뺀 결과의 절댓값을 구한 뒤, 그 값이 허용 오차(epsilon)보다 작은지 검사해야 합니다. 조건을 만족하면 두 값은 사실상 동일한 것으로 판단할 수 있습니다.
예제 코드
#include <iostream>
#include <cmath>
using namespace std;
bool compare_float(float x, float y, float epsilon = 0.01f){
if(fabs(x - y) < epsilon)
return true; // 두 값이 같음
return false; // 두 값이 다름
}
bool compare_float(double x, double y, double epsilon = 0.0000001f){
if(fabs(x - y) < epsilon)
return true; // 두 값이 같음
return false; // 두 값이 다름
}
int main() {
float x, y;
x = 22.0f/7.0f;
y = 3.1415f;
if(compare_float(x, y)){
cout << "They are equivalent" << endl;
} else {
cout << "They are not equivalent" << endl;
}
if(compare_float(x, y, 0.001f)){
cout << "They are equivalent" << endl;
} else {
cout << "They are not equivalent" << endl;
}
double a, b;
a = 2.03547415;
b = 2.03547428;
if(compare_float(a, b)){
cout << "They are equivalent" << endl;
} else {
cout << "They are not equivalent" << endl;
}
if(compare_float(a, b, 0.000001f)){
cout << "They are equivalent" << endl;
} else {
cout << "They are not equivalent" << endl;
}
}실행 결과
They are equivalent They are not equivalent They are not equivalent They are equivalent
결과 분석
x = 22/7 ≈ 3.142857과 y = 3.1415의 차이는 약 0.00136입니다. 기본 허용 오차인 0.01로 비교하면 이 차이가 오차 범위 내에 있으므로 '동일'로 판단되지만, 오차를 0.001로 줄이면 '다름'으로 판단됩니다.
마찬가지로 a = 2.03547415와 b = 2.03547428의 차이는 약 0.00000013입니다. double용 함수의 기본 허용 오차(0.0000001)보다 크기 때문에 처음에는 '다름'으로 나오지만, 오차를 0.000001로 넓히면 '동일'로 판단됩니다.
이처럼 부동 소수점 수를 비교할 때는 문제의 요구 정밀도에 맞는 적절한 epsilon 값을 선택하는 것이 핵심입니다. 실무에서는 std::abs 대신 std::fabs를 사용하고, 상대 오차를 함께 고려하는 방식도 널리 활용됩니다.