(C++ 杂记) —— 自己编写一个math类

Posted 赵萱婷

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(C++ 杂记) —— 自己编写一个math类相关的知识,希望对你有一定的参考价值。

文章目录

自己编写一个math类

概述

     在我们日常编程的过程中,经常有需要去用到处理一些数学的函数,利用他们来计算一些结果,然后很多时候,我们不止需要用到math.h提供的基础能力,因为其大部分提供的是C的基础能力,并不是面向对象的,因此就产生了一种需求,我们需要实现一个面向对象的一个有一个基础的数学能力的库,当然,自己实现的只是一个很小的需求,如果想要使用强大的数学库,自然有一些开源的,例如boost::math, opencv 里面的矩阵运算的库, 或者是cgal等等,我今天只是想写一个对于CMath库的一个基本的扩展即可。

math代码

///
// Copyright (c)2020, Tom Zhao personal. ("TZOpenTools")
// This software is a personal tools project by Tom Zhao.
// Description:
///

#ifndef _BASIC_OPEN_MATH_H_H_
#define _BASIC_OPEN_MATH_H_H_

#include <math.h>
#include <float.h>
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>

#undef min
#undef max

#define ByteSwap(val)	Basic::byteSwap(val)

namespace Basic 

	const double kDblMax = DBL_MAX;
	const double kDblMin = DBL_MIN;
	const short kShortMax = SHRT_MAX;
	const short kShortMin = SHRT_MIN;
	const unsigned short kUShortMax = USHRT_MAX;
	const unsigned short kUShortMin = 0;
	const int kIntMax = INT_MAX;
	const int kIntMin = INT_MIN;
	const unsigned int kUIntMax = UINT_MAX;
	const unsigned int kUIntMin = 0;
	const long kLongMax = LONG_MAX;
	const long kLongMin = LONG_MIN;
	const unsigned long kULongMax = ULONG_MAX;
	const unsigned long kULongMin = 0L;
	const int64_t kLLongMax = LLONG_MAX;
	const int64_t kLLongMin = LLONG_MIN;
	const uint64_t kULLongMax = ULLONG_MAX;

#if     defined(_WIN32) || defined(_WIN64) || defined(WIN32) || defined(WIN64)
	const uint64_t kULLongMin = 0ui64;
#else
	const uint64_t kULLongMin = (unsigned long long) 0u;
#endif

	const float kFltMax = FLT_MAX;
	const float kFltMin = FLT_MIN;
	const float kFltEpsilon = FLT_EPSILON;
	const float kFEpsilon = FLT_EPSILON;
	const double kDblEpsilon = DBL_EPSILON;
	const double kEpsilon = 1e-10;
	const double kEpsilon6 = 1e-6;
	const double kEpsilon7 = 1e-7;
	const double kEpsilon8 = 1e-8;
	const double kEpsilon10 = 1e-10;
	const double kEpsilon12 = 1e-12;
	const double dEpsilon = 1.0e-50;
	const double dEpsilon100 = 1.0e100;
	const double TZPI = 3.14159265358979323846;
	const double TWO_PI = TZPI * 2.0;
	const double THREE_PI = 3 * TZPI;
	const double HALF_PI = TZPI / 2.0;
	const double THERR_HALF_PI = 3.0 * HALF_PI;
	const double FIVE_HALF_PI = 5.0 * HALF_PI;
	const double SEVEN_HALF_PI = 7.0 * HALF_PI;
	const double QUARTER_PI = TZPI / 4.0;
	const double THREE_QUARTER_PI = 3.0 * QUARTER_PI;
	const double FIVE_QUARTER_PI = 5.0 * QUARTER_PI;
	const double SEVEN_QUARTER_PI = 7.0 * QUARTER_PI;
	const double RECIPOCAL_PI = 1.0 / TZPI;
	const double DEG2RAD = TZPI / 180.0;
	const double RAD2DEG = 180.0 / TZPI;
	const double GOLD = 0.618034;
	const double CGOLD = 0.381966;
	const double kArbitraryEpsilon = 0.015625;

	template<class T>
	inline const T& min(const T& a, const T& b)
	
		return a < b ? a : b;
	

	template<class T>
	inline const T& min(const T& a, const T& b, const T& c)
	
		return a < b ? min(a, c) : min(b, c);
	

	template<class T>
	inline const T& max(const T& a, const T& b)
	
		return a > b ? a : b;
	

	template<class T>
	inline const T& max(const T& a, const T& b, const T& c)
	
		return a < b ? max(a, c) : max(b, c);
	

	inline double degToRad(double deg)
	
		return deg * DEG2RAD;
	

	inline double radToDeg(double rad)
	
		return rad * RAD2DEG;
	

	inline double floor(double x)
	
		return ::floor(x);
	

	inline float floor(float x)
	
		return ::floorf(x);
	

	inline double ceil(double x)
	
		return ::ceil(x);
	

	inline float ceil(float x)
	
		return (float)((double)x);
	

	inline long truncate(float x)
	
		return (long)x;
	

	inline double round(double x)
	
		double xFloor = ::floor(x);
		return (x - xFloor >= 0.5) ? (xFloor + 1.0) : xFloor;
	

	inline double round(float x)
	
		float xFloor = ::floor(x);
		return (x - xFloor >= 0.5f) ? (xFloor + 1.0f) : xFloor;
	

	inline bool isOverflowedToLong(double x)
	
		x += 0.5;
		return ((long)x) > kLongMax;
	

	inline bool isUnderflowedToLong(double x)
	
		x -= 0.5;
		return ((long)x) < -kLongMax;
	

	inline long roundToLong(double x)
	
		x += (x > -0.0) ? 0.5 : -0.5;
		return (long)min((double)kLongMax, x);
	

	inline long roundToLong(float x)
	
		return (long)round(x);
	

	inline bool isOverflowedToInt(double x)
	
		x += 0.5;
		return ((int)x) > kIntMax;
	

	inline bool isUnderflowedToInt(double x)
	
		x -= 0.5;
		return ((int)x) < -kIntMax;
	

	inline int roundToInt(double x)
	
		if (x >= 0.)
		
			x += .5;
			if (x > double(kIntMax))
			
				return kIntMax;
			
			else
			
				return int(x);
			
		
		else
		
			x -= .5;
			if (x < double(kIntMin))
			
				return kIntMin;
			
			else
			
				return int(x);
			
		
	

	inline int roundToInt(float x)
	
		return (int)round(x);
	

	template<class T>
	inline T lerp(const T& a, const T& b, float t)
	
		return (T)(a * (1.0f - t) + b * t);
	

	template<class T>
	inline T lerp(const T& a, const T& b, double t)
	
		return (T)(a * (1.0 - t) + b * t);
	

	template<class T>
	inline const T clamp(const T& t, const T& low, const T& high)
	
		if (t < low)
		
			return low;
		
		if (t > high)
		
			return high;
		

		return t;
	

	template<class T>
	inline const T abs(const T& a)
	
		return a < (T)0 ? -a : a;
	

	template<class T>
	inline const T sign(const T& a)
	
		if (a == (T)0)
		
			return 0;
		
		else if (a > (T)0)
		
			return 1;
		
		else
		
			return -1;
		
	

	inline long double fabs(long double x)
	
		return ::fabs(x);
	

	inline double fabs(double x)
	
		return ::fabs(x);
	

	inline float fabs(float x)
	
		return ::fabs(x);
	

	inline bool isPositive(double x, double tol = kEpsilon)
	
		return (x > tol);
	

	inline bool isPositive(float x, float tol = kFEpsilon)
	
		return (x < -tol);
	

	inline bool isNegative(double x, double tol = kEpsilon)
	
		return (x < -tol);
	

	inline bool isNegative(float x, float tol = kFEpsilon)
	
		return (x < -tol);
	

	inline bool isZero(double x, double tol = kEpsilon)
	
		return !isPositive(x, tol) && !isNegative(x, tol);
	

	inline bool isZero(float x, float tol = kFEpsilon)
	
		return !isPositive(x, tol) && !isNegative(x, tol);
	

	template <typename T>
	inline bool isZero(const T& x)
	
		return (x == (T)0);
	

	inline bool isNonZero(double x, double tol = kEpsilon)
	
		return isPositive(x, tol) || isNonZero(x, tol);
	

	inline bool isEqual(double x, double y, double tol = kEpsilon)
	
		return isZero(x - y, tol);
	

	inline bool isEqual(float x, float y, float tol = kFEpsilon)
	
		return isZero(x - y, tol);
	

	inline bool isEqual(long x, long y, long tol = 0)
	
		return ((x - y) <= tol && (x - y) >= -tol);
	

	template <typename T>
	inline bool isEqual(const T& x, const T& y)
	
		return (x == y);
	

	inline int doubleCmp(double x, double y, double tol = kEpsilon)
	
		if (isPositive(x - y, tol))
		
			return 1;
		
		if (isNegative(x - y, tol))
		
			return -1;
		
		return 0;
	

	template <typename TInteger>
	inline void divide(const TInteger& number, const TInteger& denom, TInteger& quotient, TInteger& remainder)
	
		quotient = number / denom;
		remainder = number % denom;
	

	inline double  safeDivide(double a, double b)
	
		if (a == 0.)
		
			return 0.;
		
		if (b != 0.)
		
			static const int maxBinExp = 997;
			int nExpA, nExpB;
			double dMantissa = frexp(a, &nExpA);
			dMantissa = frexp(b, &nExpB);
			if ((nExpA - nExpB) < maxBinExp)
			
				return a / b;
			
		

		bool bNeg = (a < 0.);
		if (b < 0.)
		
			bNeg = !bNeg;
		
		return bNeg ? -1.e+300 : 1.e+300;
	

	inline double sqrt(double x)
	
		assert(x >= 0.0);
		return ::sqrt(x);
	

	inline float sqrt(float x)
	
		assert(x >= 0.0f);
		return (float)::sqrt((double)x);
	

	template<typename T>
	inline const T sqsum(const T& x, const T& y)
	
		return x * x + y * y;
	

	template<typename T>
	inline const T sqsum(const T& x, const T& y, const T& z)
	
		return x * x + y * y + z * z;
	

	template<typename T>
	inline double sqrt(const T& x, const T& y)
	
		return sqrt((double)sqsum(x, y以上是关于(C++ 杂记) —— 自己编写一个math类的主要内容,如果未能解决你的问题,请参考以下文章

(Visual Studio 杂记) )—— Visual Studio 如何 设置 C++ 标准版本

(工作效率提升杂记) —— Visual Studio 效率提升类的的工具和设置(个人)

(工作效率提升杂记) —— Visual Studio 效率提升类的的工具和设置(个人)

(经验杂记) —— Visual Studio 运行程序时关闭Assert的弹出

(经验杂记) —— Visual Studio 运行程序时关闭Assert的弹出

杂记6--一些c++踩过的坑