您的位置:首页 > 编程语言 > C语言/C++

C++源码分享(一):浮点数比较类

2010-08-03 11:09 351 查看
浮点数比较是常见应用程序特别是矢量图形类数据常见的需要,使用方法参见测试函数

//**********************************************************************

// 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宏
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: