Make Unreal REAL.
article thumbnail
Published 2023. 1. 30. 10:23
실수를 비교하는 방법 C++/기타

 

부동 소수점 실수는 수를 정확히 표현할 수 없고 오차가 존재한다.

 

유니티나 언리얼 에디터에서 1이었던 값이 0.99999로 바뀌어 있는 걸 본 적이 있을 것이다.

 

따라서 실수가 같은지 비교하는 것은 사실 그리 간단하지 않다.

 

대략 같다.

<cpp />
// 절댓값(a - b) <= 절댓값이 크다고 추측되는 수 * Epsilon bool approximatelyEqual(float a, float b) { return fabs(a - b) <= (fabs(a) < fabs(b) ? fabs(b) : fabs(a)) * EPSILON; }

 

본질적으로 같다.

<cpp />
// 절댓값(a - b) <= 절댓값이 작다고 추측되는 수 * Epsilon bool essentiallyEqual(float a, float b) { return fabs(a - b) <= (fabs(a) > fabs(b) ? fabs(b) : fabs(a)) * EPSILON; }

 

명확하게 크다.

<cpp />
// a - b > 절댓값이 크다고 추측되는 수 * Epsilon bool definitelyGreaterThan(float a, float b) { return (a - b) > (fabs(a) < fabs(b) ? fabs(b) : fabs(a)) * EPSILON; }

 

명확하게 작다.

<cpp />
// b - a > 절댓값이 크다고 추측되는 수 * Epsilon bool definitelyLessThan(float a, float b) { return (b - a) > (fabs(a) < fabs(b) ? fabs(b) : fabs(a)) * EPSILON; }

 

예시

 

<cpp />
#include <iostream> #include <limits> #define EPSILON numeric_limits<float>::epsilon() using namespace std; // 절댓값(a - b) <= 절댓값이 크다고 추측되는 수 * Epsilon bool approximatelyEqual(float a, float b) { return fabs(a - b) <= (fabs(a) < fabs(b) ? fabs(b) : fabs(a)) * EPSILON; } // 절댓값(a - b) <= 절댓값이 작다고 추측되는 수 * Epsilon bool essentiallyEqual(float a, float b) { return fabs(a - b) <= (fabs(a) > fabs(b) ? fabs(b) : fabs(a)) * EPSILON; } // a - b > 절댓값이 크다고 추측되는 수 * Epsilon bool definitelyGreaterThan(float a, float b) { return (a - b) > (fabs(a) < fabs(b) ? fabs(b) : fabs(a)) * EPSILON; } // b - a > 절댓값이 크다고 추측되는 수 * Epsilon bool definitelyLessThan(float a, float b) { return (b - a) > (fabs(a) < fabs(b) ? fabs(b) : fabs(a)) * EPSILON; } int main(int argc, char* argv[]) { float a = 5.0, b = 5.0; cout << "approximatelyEqual(" << a << ", " << b << "): " << boolalpha << approximatelyEqual(a, b) << endl << endl; cout << "essentiallyEqual(" << a << ", " << b << "): " << boolalpha << essentiallyEqual(a, b) << endl << endl; cout << "definitelyGreaterThan(" << a << ", " << b << "): " << boolalpha << definitelyGreaterThan(a, b) << endl << endl; cout << "definitelyLessThan(" << a << ", " << b << "): " << boolalpha << definitelyLessThan(a, b) << endl << endl; a = 5.00001; b = 5.00002; cout << "approximatelyEqual(" << a << ", " << b << "): " << boolalpha << approximatelyEqual(a, b) << endl << endl; cout << "essentiallyEqual(" << a << ", " << b << "): " << boolalpha << essentiallyEqual(a, b) << endl << endl; cout << "definitelyGreaterThan(" << a << ", " << b << "): " << boolalpha << definitelyGreaterThan(a, b) << endl << endl; cout << "definitelyLessThan(" << a << ", " << b << "): " << boolalpha << definitelyLessThan(a, b) << endl << endl; return 0; }

 

출력

<cpp />
approximatelyEqual(5, 5): true essentiallyEqual(5, 5): true definitelyGreaterThan(5, 5): false definitelyLessThan(5, 5): false approximatelyEqual(5.00001, 5.00002): false essentiallyEqual(5.00001, 5.00002): false definitelyGreaterThan(5.00001, 5.00002): false definitelyLessThan(5.00001, 5.00002): true

'C++ > 기타' 카테고리의 다른 글

배열의 크기를 확인할 때 주의할 점  (0) 2023.02.13
디폴트 매개변수(Default Parameter)  (0) 2023.01.30
람다 식(Lambda expression)  (0) 2023.01.21
펑터(Functor)  (0) 2023.01.21
템플릿(Template)  (0) 2023.01.20
profile

Make Unreal REAL.

@diesuki4

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

검색 태그