728x90
300x250
[C, C++] double의 비교
float, double의 경우, 비교 자체가 소수 점이라는 것이 있어서 어렵습니다.
단순 비교를 해버리면 안되는 게 1.xxxxxxxx 의 경우, 1로 절삭 처리됩니다.
컴파일러가 멍청해서 그런 것도 있지만, 소수 점은 Science에선 중요한 거지만, 단순한 명령을 처리하는 컴퓨터 입장에선 엄밀한 것과 정확성을 보장해주는 자료형이 더 좋은 것입니다.
예를 들면, 스위치 On, Off와 같이 1, 0이 컴퓨터 입장에선 더 직관적이고 엄밀한 자료가 될 수 있습니다.
float, double형의 경우, IEEE 754 규약에 의해 부동소수점의 원칙을 기반으로 한 별도의 코딩을 통해 비교를 처리해야 합니다.
아래의 코드는 구글에 근무하는 brucedawson씨가 소개한 개념을 바탕으로 Ulps기반의 Double형 비교를 위한 코드를 DevMachine님이 개발한 코드입니다.
int CompareDoubleAbsoulteAndUlps(double x,
double y,
double absTolerance = (1.0e-8),
int ulpsTolerance = 4)
{
double diff = x - y;
if (fabs(diff) <= absTolerance)
return 0;
__int64 nx = *((__int64*)&x);
__int64 ny = *((__int64*)&y);
if ((nx & 0x8000000000000000) != (ny & 0x8000000000000000))
return (diff > 0) ? 1 : -1;
__int64 ulpsDiff = nx - ny;
if ((ulpsDiff >= 0 ? ulpsDiff : -ulpsDiff) <= ulpsTolerance)
return 0;
return (diff > 0) ? 1 : -1;
}
double y,
double absTolerance = (1.0e-8),
int ulpsTolerance = 4)
{
double diff = x - y;
if (fabs(diff) <= absTolerance)
return 0;
__int64 nx = *((__int64*)&x);
__int64 ny = *((__int64*)&y);
if ((nx & 0x8000000000000000) != (ny & 0x8000000000000000))
return (diff > 0) ? 1 : -1;
__int64 ulpsDiff = nx - ny;
if ((ulpsDiff >= 0 ? ulpsDiff : -ulpsDiff) <= ulpsTolerance)
return 0;
return (diff > 0) ? 1 : -1;
}
1. 참고자료(Reference)
1. Comparing floating point numbers - Bruce Dawson
2. Comparing Floating Point Numbers, 2012 Edition
3. http://devmachine.blog.me/220119534107
정확히 이해하려면, 여기에 설명하는 것보단 IEEE 754의 부동소수점에 대해 공부해보시는 게 훨씬 빠를 거 같다는 생각을 해봅니다.
저는 참고 인용 문구를 통해 코드 배포 목적으로 이 글을 정리하고자 합니다.
반응형
'소프트웨어(SW) > GNU - C, C++' 카테고리의 다른 글
[GNU - C, C++] 리눅스(Linux) - 사진 압축 자동화 도구(g++, 쉘(Shell)) (1/2) (132) | 2021.04.11 |
---|---|
[C++(GTKmm)] Anjuta에서 GTKmm 시작하기 (7) | 2019.07.24 |
[C, C++] Header와 템플릿의 명시적 특수화 (9) | 2014.10.18 |
[G++/C++]: std::to_string -> compiler error "not a member of std" - 오류 (12) | 2014.10.12 |
[C++] String 함수 - 문자열 비교 방법 (9) | 2014.10.11 |