greenplumn CDouble 源码

  • 2022-08-18
  • 浏览 (341)

greenplumn CDouble 代码

文件路径:/src/backend/gporca/libgpos/include/gpos/common/CDouble.h

//---------------------------------------------------------------------------
//	Greenplum Database
//	Copyright (C) 2012 EMC Corp.
//
//	@filename:
//		CDouble.h
//
//	@doc:
//		Safe implementation of floating point numbers and operations.
//---------------------------------------------------------------------------
#ifndef GPOS_CDouble_H
#define GPOS_CDouble_H

#include <math.h>

#include "gpos/base.h"

#define GPOS_FP_ABS_MIN (1e-250)  // min value: 4.94066e-324
#define GPOS_FP_ABS_MAX (1e+250)  // max value: 8.98847e+307

namespace gpos
{
//---------------------------------------------------------------------------
//	@class:
//		CDouble
//
//	@doc:
//		Class representing floating-point numbers
//
//---------------------------------------------------------------------------
class CDouble
{
private:
	// double-precision value
	DOUBLE m_d;

	// check validity in ctor
	inline void
	CheckValidity()
	{
		GPOS_ASSERT(0.0 < GPOS_FP_ABS_MIN);
		GPOS_ASSERT(GPOS_FP_ABS_MIN < GPOS_FP_ABS_MAX);

		double abs_value = fabs(m_d);

		if (GPOS_FP_ABS_MAX < abs_value)
		{
			SetSignedVal(GPOS_FP_ABS_MAX);
		}

		if (GPOS_FP_ABS_MIN > abs_value)
		{
			SetSignedVal(GPOS_FP_ABS_MIN);
		}
	}

	// assign value while maintaining current sign
	inline void
	SetSignedVal(DOUBLE val)
	{
		if (0.0 <= m_d)
		{
			m_d = val;
		}
		else
		{
			m_d = -val;
		}
	}


public:
	// ctors
	inline CDouble(DOUBLE d) : m_d(d)
	{
		CheckValidity();
	}

	inline CDouble(ULLONG ull) : m_d(DOUBLE(ull))
	{
		CheckValidity();
	}

	inline CDouble(ULONG ul) : m_d(DOUBLE(ul))
	{
		CheckValidity();
	}

	inline CDouble(LINT li) : m_d(DOUBLE(li))
	{
		CheckValidity();
	}

	inline CDouble(INT i) : m_d(DOUBLE(i))
	{
		CheckValidity();
	}

	// value accessor
	inline DOUBLE
	Get() const
	{
		return m_d;
	}

	// arithmetic operators
	friend CDouble
	operator+(const CDouble &left, const CDouble &right)
	{
		return CDouble(left.m_d + right.m_d);
	}

	friend CDouble
	operator-(const CDouble &left, const CDouble &right)
	{
		return CDouble(left.m_d - right.m_d);
	}

	friend CDouble
	operator*(const CDouble &left, const CDouble &right)
	{
		return CDouble(left.m_d * right.m_d);
	}

	friend CDouble
	operator/(const CDouble &left, const CDouble &right)
	{
		return CDouble(left.m_d / right.m_d);
	}

	// negation
	friend CDouble
	operator-(const CDouble &d)
	{
		return CDouble(-d.m_d);
	}

	// logical operators
	friend BOOL
	operator==(const CDouble &left, const CDouble &right)
	{
		CDouble fpCompare(left.m_d - right.m_d);

		return (fabs(fpCompare.m_d) == GPOS_FP_ABS_MIN);
	}

	friend BOOL operator!=(const CDouble &left, const CDouble &right);
	friend BOOL operator<(const CDouble &left, const CDouble &right);
	friend BOOL operator<=(const CDouble &left, const CDouble &right);
	friend BOOL
	operator>(const CDouble &left, const CDouble &right)
	{
		CDouble fpCompare(left.m_d - right.m_d);

		return (fpCompare.m_d > GPOS_FP_ABS_MIN);
	}

	friend BOOL operator>=(const CDouble &left, const CDouble &right);

	// absolute
	inline CDouble
	Absolute() const
	{
		return CDouble(fabs(m_d));
	}

	// floor
	inline CDouble
	Floor() const
	{
		return CDouble(floor(m_d));
	}

	// ceiling
	inline CDouble
	Ceil() const
	{
		return CDouble(ceil(m_d));
	}

	// power
	inline CDouble
	Pow(const CDouble &d) const
	{
		return CDouble(pow(m_d, d.m_d));
	}

	// log to the base 2
	inline CDouble
	Log2() const
	{
		return CDouble(log2(m_d));
	}

	// print to stream
	inline IOstream &
	OsPrint(IOstream &os) const
	{
		return os << m_d;
	}

	// compare two double values using given precision
	inline static BOOL
	Equals(DOUBLE dLeft, DOUBLE dRight, DOUBLE dPrecision = GPOS_FP_ABS_MIN)
	{
		return fabs(dRight - dLeft) <= dPrecision;
	}

};	// class CDouble

// arithmetic operators
inline CDouble operator+(const CDouble &left, const CDouble &right);
inline CDouble operator-(const CDouble &left, const CDouble &right);
inline CDouble operator*(const CDouble &left, const CDouble &right);
inline CDouble operator/(const CDouble &left, const CDouble &right);

// logical operators
inline BOOL operator==(const CDouble &left, const CDouble &right);
inline BOOL operator>(const CDouble &left, const CDouble &right);

// negation
inline CDouble operator-(const CDouble &d);

// '!=' operator
inline BOOL
operator!=(const CDouble &left, const CDouble &right)
{
	return (!(left == right));
}

// '<=' operator
inline BOOL
operator>=(const CDouble &left, const CDouble &right)
{
	return (left == right || left > right);
}

// '>' operator
inline BOOL
operator<(const CDouble &left, const CDouble &right)
{
	return (right > left);
}

// '>=' operator
inline BOOL
operator<=(const CDouble &left, const CDouble &right)
{
	return (right == left || right > left);
}

// print shorthand
inline IOstream &
operator<<(IOstream &os, CDouble d)
{
	return d.OsPrint(os);
}
}  // namespace gpos

#endif	// !GPOS_CDouble_H

// EOF

相关信息

greenplumn 源码目录

相关文章

greenplumn CAutoP 源码

greenplumn CAutoRef 源码

greenplumn CAutoRg 源码

greenplumn CAutoTimer 源码

greenplumn CBitSet 源码

greenplumn CBitSetIter 源码

greenplumn CBitVector 源码

greenplumn CDebugCounter 源码

greenplumn CDynamicPtrArray 源码

greenplumn CEnumSet 源码

0  赞