浮点数比较是常见应用程序特别是矢量图形类数据常见的需要,使用方法参见测试函数
//**********************************************************************
// Copyright (c) 2010
// 迪斯特软件开发小组.
// 文件: FloatCompare.hpp
// 内容: 浮点数比较类
// 历史:
// 序号 修改时间 修改人 修改内容
// 1 2010-7-21 hlq 首次生成
//*********************************************************************
//声明本头文件宏
#ifndef _FLOATCOMPARE_HPP
#define _FLOATCOMPARE_HPP
//包含头文件
#include <cassert>
////////////////////////////////////////////////// 浮点数精度特征 ///////////////////////////////////////////////////
//**********************************************************************
// 类名: EPSTraits
// 目的: 容许误差特征类
//*********************************************************************
template<typename T>
struct EPSTraits
{
typedef T value_type;
};
//**********************************************************************
// 类名: EPSTraits
// 目的: 容许误差特征类(浮点数特化)
//*********************************************************************
template<>
struct EPSTraits<float>
{
typedef float value_type;
enum{precision = 10000};
};
//**********************************************************************
// 类名: EPSTraits
// 目的: 容许误差特征类(浮点数特化)
//*********************************************************************
template<>
struct EPSTraits<double>
{
typedef double value_type;
enum{precision = 10000};
};
////////////////////////////////////////////////// 不等于比较 ///////////////////////////////////////////////////
//**********************************************************************
// 函数: Unequal
// 功能: 不相等比较
//*********************************************************************
template <typename T,typename U>
inline bool Unequal(const T& a,const U& b)
{
return a != b;
}
//**********************************************************************
// 函数: Unequal
// 功能: 不相等比较(单精度浮点数特化)
//*********************************************************************
template <typename T>
inline bool Unequal(const T& a,float b,float dEPS = 1.0f / EPSTraits<float>::precision)
{
return (a < (b - dEPS)) || (a > (b + dEPS));
}
//**********************************************************************
// 函数: Unequal
// 功能: 不相等比较(单精度浮点数特化)
//*********************************************************************
template <typename U>
inline bool Unequal(float a,const U& b,float dEPS = 1.0f / EPSTraits<float>::precision)
{
return Unequal(b,a,dEPS);
}
//**********************************************************************
// 函数: Unequal
// 功能: 不相等比较(单精度浮点数特化)
//*********************************************************************
inline bool Unequal(float a,float b,float dEPS = 1.0f / EPSTraits<float>::precision)
{
return (a < (b - dEPS)) || (a > (b + dEPS));
}
//**********************************************************************
// 函数: Unequal
// 功能: 不相等比较(双精度浮点数特化)
//*********************************************************************
template <typename T>
inline bool Unequal(const T& a,double b,double dEPS = 1.0f / EPSTraits<double>::precision)
{
return (a < (b - dEPS)) || (a > (b + dEPS));
}
//**********************************************************************
// 函数: Unequal
// 功能: 不相等比较(双精度浮点数特化)
//*********************************************************************
template <typename U>
inline bool Unequal(double a,const U& b,double dEPS = 1.0f / EPSTraits<double>::precision)
{
return Unequal(b,a,dEPS);
}
//**********************************************************************
// 函数: Unequal
// 功能: 不相等比较(单精度浮点数特化)
//*********************************************************************
inline bool Unequal(double a,double b,double dEPS = 1.0f / EPSTraits<double>::precision)
{
return (a < (b - dEPS)) || (a > (b + dEPS));
}
////////////////////////////////////////////////// 等于比较 ///////////////////////////////////////////////////
//**********************************************************************
// 函数: Equal
// 功能: 相等比较
//*********************************************************************
template <typename T,typename U>
inline bool Equal(const T& a,const U& b)
{
return a == b;
}
//**********************************************************************
// 函数: Equal
// 功能: 相等比较(单精度浮点数特化)
//*********************************************************************
template <typename T>
inline bool Equal(const T& a,float b,float dEPS = 1.0f / EPSTraits<float>::precision)
{
return !Unequal(a,b,dEPS);
}
//**********************************************************************
// 函数: Equal
// 功能: 相等比较(单精度浮点数特化)
//*********************************************************************
template <typename U>
inline bool Equal(float a,const U& b,float dEPS = 1.0f / EPSTraits<float>::precision)
{
return !Unequal(a,b,dEPS);
}
//**********************************************************************
// 函数: Equal
// 功能: 相等比较(单精度浮点数特化)
//*********************************************************************
inline bool Equal(float a,float b,float dEPS = 1.0f / EPSTraits<float>::precision)
{
return !Unequal(a,b,dEPS);
}
//**********************************************************************
// 函数: Equal
// 功能: 相等比较(双精度浮点数特化)
//*********************************************************************
template <typename T>
inline bool Equal(const T& a,double b,double dEPS = 1.0f / EPSTraits<double>::precision)
{
return !Unequal(a,b,dEPS);
}
//**********************************************************************
// 函数: Equal
// 功能: 相等比较(双精度浮点数特化)
//*********************************************************************
template <typename U>
inline bool Equal(double a,const U& b,double dEPS = 1.0f / EPSTraits<double>::precision)
{
return !Unequal(a,b,dEPS);
}
//**********************************************************************
// 函数: Equal
// 功能: 相等比较(单精度浮点数特化)
//*********************************************************************
inline bool Equal(double a,double b,double dEPS = 1.0f / EPSTraits<double>::precision)
{
return !Unequal(a,b,dEPS);
}
////////////////////////////////////////////////// 小于比较 ///////////////////////////////////////////////////
//**********************************************************************
// 函数: Less
// 功能: 小于比较
//*********************************************************************
template <typename T,typename U>
inline bool Less(const T& a,const U& b)
{
return a < b;
}
//**********************************************************************
// 函数: Less
// 功能: 小于比较(单精度浮点数特化)
//*********************************************************************
template <typename T>
inline bool Less(const T& a,float b,float dEPS = 1.0f / EPSTraits<float>::precision)
{
return a < (b - dEPS);
}
//**********************************************************************
// 函数: Less
// 功能: 小于比较(单精度浮点数特化)
//*********************************************************************
template <typename U>
inline bool Less(float a,const U& b,float dEPS = 1.0f / EPSTraits<float>::precision)
{
return (a + dEPS) < b;
}
//**********************************************************************
// 函数: Less
// 功能: 小于比较(单精度浮点数特化)
//*********************************************************************
inline bool Less(float a,float b,float dEPS = 1.0f / EPSTraits<float>::precision)
{
return a < (b - dEPS);
}
//**********************************************************************
// 函数: Less
// 功能: 小于比较(双精度浮点数特化)
//*********************************************************************
template <typename T>
inline bool Less(const T& a,double b,double dEPS = 1.0f / EPSTraits<double>::precision)
{
return a < (b - dEPS);
}
//**********************************************************************
// 函数: Less
// 功能: 小于比较(双精度浮点数特化)
//*********************************************************************
template <typename U>
inline bool Less(double a,const U& b,double dEPS = 1.0f / EPSTraits<double>::precision)
{
return (a + dEPS) < b;
}
//**********************************************************************
// 函数: Less
// 功能: 小于比较(单精度浮点数特化)
//*********************************************************************
inline bool Less(double a,double b,double dEPS = 1.0f / EPSTraits<double>::precision)
{
return a < (b - dEPS);
}
////////////////////////////////////////////////// 大于比较 ///////////////////////////////////////////////////
//**********************************************************************
// 函数: Great
// 功能: 大于比较
//*********************************************************************
template <typename T,typename U>
inline bool Great(const T& a,const U& b)
{
return a > b;
}
//**********************************************************************
// 函数: Great
// 功能: 大于比较(单精度浮点数特化)
//*********************************************************************
template <typename T>
inline bool Great(const T& a,float b,float dEPS = 1.0f / EPSTraits<float>::precision)
{
return a > (b + dEPS);
}
//**********************************************************************
// 函数: Great
// 功能: 大于比较(单精度浮点数特化)
//*********************************************************************
template <typename U>
inline bool Great(float a,const U& b,float dEPS = 1.0f / EPSTraits<float>::precision)
{
return (a - dEPS) > b;
}
//**********************************************************************
// 函数: Great
// 功能: 大于比较(单精度浮点数特化)
//*********************************************************************
inline bool Great(float a,float b,float dEPS = 1.0f / EPSTraits<float>::precision)
{
return a > (b + dEPS);
}
//**********************************************************************
// 函数: Great
// 功能: 大于比较(双精度浮点数特化)
//*********************************************************************
template <typename T>
inline bool Great(const T& a,double b,double dEPS = 1.0f / EPSTraits<double>::precision)
{
return a > (b + dEPS);
}
//**********************************************************************
// 函数: Great
// 功能: 大于比较(双精度浮点数特化)
//*********************************************************************
template <typename U>
inline bool Great(double a,const U& b,double dEPS = 1.0f / EPSTraits<double>::precision)
{
return (a - dEPS) > b;
}
//**********************************************************************
// 函数: Great
// 功能: 大于比较(单精度浮点数特化)
//*********************************************************************
inline bool Great(double a,double b,double dEPS = 1.0f / EPSTraits<double>::precision)
{
return a > (b + dEPS);
}
////////////////////////////////////////////////// 小于等于比较 ///////////////////////////////////////////////////
//**********************************************************************
// 函数: LessEqual
// 功能: 小于等于比较
//*********************************************************************
template <typename T,typename U>
inline bool LessEqual(const T& a,const U& b)
{
return a <= b;
}
//**********************************************************************
// 函数: LessEqual
// 功能: 小于等于比较(单精度浮点数特化)
//*********************************************************************
template <typename T>
inline bool LessEqual(const T& a,float b,float dEPS = 1.0f / EPSTraits<float>::precision)
{
return !Great(a,b,dEPS);
}
//**********************************************************************
// 函数: LessEqual
// 功能: 小于等于比较(单精度浮点数特化)
//*********************************************************************
template <typename U>
inline bool LessEqual(float a,const U& b,float dEPS = 1.0f / EPSTraits<float>::precision)
{
return !Great(a,b,dEPS);
}
//**********************************************************************
// 函数: LessEqual
// 功能: 小于等于比较(单精度浮点数特化)
//*********************************************************************
inline bool LessEqual(float a,float b,float dEPS = 1.0f / EPSTraits<float>::precision)
{
return !Great(a,b,dEPS);
}
//**********************************************************************
// 函数: LessEqual
// 功能: 小于等于比较(双精度浮点数特化)
//*********************************************************************
template <typename T>
inline bool LessEqual(const T& a,double b,double dEPS = 1.0f / EPSTraits<double>::precision)
{
return !Great(a,b,dEPS);
}
//**********************************************************************
// 函数: LessEqual
// 功能: 小于等于比较(双精度浮点数特化)
//*********************************************************************
template <typename U>
inline bool LessEqual(double a,const U& b,double dEPS = 1.0f / EPSTraits<double>::precision)
{
return !Great(a,b,dEPS);
}
//**********************************************************************
// 函数: LessEqual
// 功能: 小于等于比较(单精度浮点数特化)
//*********************************************************************
inline bool LessEqual(double a,double b,double dEPS = 1.0f / EPSTraits<double>::precision)
{
return !Great(a,b,dEPS);
}
////////////////////////////////////////////////// 大于等于比较 ///////////////////////////////////////////////////
//**********************************************************************
// 函数: GreatEqual
// 功能: 大于等于比较
//*********************************************************************
template <typename T,typename U>
inline bool GreatEqual(const T& a,const U& b)
{
return a >= b;
}
//**********************************************************************
// 函数: GreatEqual
// 功能: 大于等于比较(单精度浮点数特化)
//*********************************************************************
template <typename T>
inline bool GreatEqual(const T& a,float b,float dEPS = 1.0f / EPSTraits<float>::precision)
{
return !Less(a,b,dEPS);
}
//**********************************************************************
// 函数: GreatEqual
// 功能: 大于等于比较(单精度浮点数特化)
//*********************************************************************
template <typename U>
inline bool GreatEqual(float a,const U& b,float dEPS = 1.0f / EPSTraits<float>::precision)
{
return !Less(a,b,dEPS);
}
//**********************************************************************
// 函数: GreatEqual
// 功能: 大于等于比较(单精度浮点数特化)
//*********************************************************************
inline bool GreatEqual(float a,float b,float dEPS = 1.0f / EPSTraits<float>::precision)
{
return !Less(a,b,dEPS);
}
//**********************************************************************
// 函数: GreatEqual
// 功能: 大于等于比较(双精度浮点数特化)
//*********************************************************************
template <typename T>
inline bool GreatEqual(const T& a,double b,double dEPS = 1.0f / EPSTraits<double>::precision)
{
return !Less(a,b,dEPS);
}
//**********************************************************************
// 函数: GreatEqual
// 功能: 大于等于比较(双精度浮点数特化)
//*********************************************************************
template <typename U>
inline bool GreatEqual(double a,const U& b,double dEPS = 1.0f / EPSTraits<double>::precision)
{
return !Less(a,b,dEPS);
}
//**********************************************************************
// 函数: GreatEqual
// 功能: 大于等于比较(单精度浮点数特化)
//*********************************************************************
inline bool GreatEqual(double a,double b,double dEPS = 1.0f / EPSTraits<double>::precision)
{
return !Less(a,b,dEPS);
}
//**********************************************************************
// 函数: FloatCompare_Test
// 功能: 浮点数比较测试
//*********************************************************************
template<typename DummyType>
inline void FloatCompare_Test(void)
{
//测试用例1: 等于测试
int nValue = 3;
float dEPS = 1.0f / EPSTraits<float>::precision;
float dEPS_Half = dEPS / 2;
float dEPS_Double = dEPS * 2;
float dEPS_Third = dEPS * 3;
assert(Equal(nValue,nValue));
assert(Equal(nValue,nValue + dEPS_Half));
assert(Equal(nValue + dEPS_Half,nValue + dEPS_Half));
assert(Equal(nValue + dEPS_Half , nValue));
assert(!Equal(nValue,nValue + dEPS_Double));
assert(!Equal(nValue + dEPS_Double,nValue));
assert(Equal(nValue + dEPS_Double,nValue,dEPS_Third));
assert(Equal(nValue,nValue + dEPS_Double,dEPS_Third));
assert(!Equal(nValue + dEPS_Double * 2,nValue,dEPS_Third));
assert(!Equal(nValue,nValue + dEPS_Double * 2,dEPS_Third));
//测试用例2: 不等于测试
int nValue2 = nValue + 1;
assert(Unequal(nValue,nValue2));
assert(!Unequal(nValue,nValue + dEPS_Half));
assert(!Unequal(nValue + dEPS_Half , nValue));
assert(!Unequal(nValue + dEPS_Half,nValue + dEPS_Half));
assert(Unequal(nValue,nValue + dEPS_Double));
assert(Unequal(nValue + dEPS_Double,nValue));
assert(!Unequal(nValue + dEPS_Double,nValue,dEPS_Third));
assert(!Unequal(nValue,nValue + dEPS_Double,dEPS_Third));
assert(Unequal(nValue + dEPS_Double * 2,nValue,dEPS_Third));
assert(Unequal(nValue,nValue + dEPS_Double * 2,dEPS_Third));
//测试用例3: 小于测试
assert(Less(nValue,nValue2));
assert(!Less(nValue,nValue + dEPS_Half));
assert(!Less(nValue + dEPS_Half , nValue));
assert(!Less(nValue + dEPS_Half,nValue + dEPS_Half));
assert(Less(nValue,nValue + dEPS_Double));
assert(!Less(nValue + dEPS_Double,nValue));
assert(!Less(nValue + dEPS_Double,nValue,dEPS_Third));
assert(!Less(nValue,nValue + dEPS_Double,dEPS_Third));
assert(!Less(nValue + dEPS_Double * 2,nValue,dEPS_Third));
assert(Less(nValue,nValue + dEPS_Double * 2,dEPS_Third));
//测试用例4: 大于测试
assert(!Great(nValue,nValue2));
assert(!Great(nValue,nValue + dEPS_Half));
assert(!Great(nValue + dEPS_Half , nValue));
assert(!Great(nValue + dEPS_Half,nValue + dEPS_Half));
assert(!Great(nValue,nValue + dEPS_Double));
assert(Great(nValue + dEPS_Double,nValue));
assert(!Great(nValue + dEPS_Double,nValue,dEPS_Third));
assert(!Great(nValue,nValue + dEPS_Double,dEPS_Third));
assert(Great(nValue + dEPS_Double * 2,nValue,dEPS_Third));
assert(!Great(nValue,nValue + dEPS_Double * 2,dEPS_Third));
//测试用例5: 小于等于测试
assert(LessEqual(nValue,nValue2));
assert(LessEqual(nValue,nValue));
assert(LessEqual(nValue,nValue + dEPS_Half));
assert(LessEqual(nValue + dEPS_Half , nValue));
assert(LessEqual(nValue + dEPS_Half,nValue + dEPS_Half));
assert(LessEqual(nValue,nValue + dEPS_Double));
assert(!LessEqual(nValue + dEPS_Double,nValue));
assert(LessEqual(nValue + dEPS_Double,nValue,dEPS_Third));
assert(LessEqual(nValue,nValue + dEPS_Double,dEPS_Third));
assert(!LessEqual(nValue + dEPS_Double * 2,nValue,dEPS_Third));
assert(LessEqual(nValue,nValue + dEPS_Double * 2,dEPS_Third));
//测试用例6: 大于等于测试
assert(!GreatEqual(nValue,nValue2));
assert(GreatEqual(nValue,nValue));
assert(GreatEqual(nValue,nValue + dEPS_Half));
assert(GreatEqual(nValue + dEPS_Half , nValue));
assert(GreatEqual(nValue + dEPS_Half,nValue + dEPS_Half));
assert(!GreatEqual(nValue,nValue + dEPS_Double));
assert(GreatEqual(nValue + dEPS_Double,nValue));
assert(GreatEqual(nValue + dEPS_Double,nValue,dEPS_Third));
assert(GreatEqual(nValue,nValue + dEPS_Double,dEPS_Third));
assert(GreatEqual(nValue + dEPS_Double * 2,nValue,dEPS_Third));
assert(!GreatEqual(nValue,nValue + dEPS_Double * 2,dEPS_Third));
}
#endif //假如未定义_FLOATCOMPARE_HPP宏