(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的弹出