MyDog--类型--浮点数

浮点数有2个问题,精度问题和数据不一致问题.

  1. 精度问题就是由于存储空间有限,二进制里的无限循环存不下而导致的,会干扰判断.
  2. 数据不一致指浮点数存成二进制数据后,在不同的端可能解析出来的数值有差异.这就是为什么帧同步的协议,都使用自定义整数存储浮点数数据.

基于上述2点,我打算自己封装个以整数存储的浮点数.统一精度,解决上述2个问题.唯二代价就是取值范围缩少和运算时候多了一步个乘/除运算.

原理很简单,假设精度是0.0001(即万分比),那么转换成自定义浮点数的时候,数值要乘以10000

首先是定义个全局的精度.  之前我写成了float  S_accuracy,这样是不对的!!!

static int S_accuracy = 10000;//默认精度是0.0001

先定义几个宏,是不是没有除法?因为要判断被除数为0的异常

// == != < <= > >=
#define OPER_FUN_BOOL(Symbol,Type) inline bool operator Symbol(const Type& mdt){\
	return data Symbol mdt.data;\
	}\
// + -  
#define OPER_FUN_MD(Symbol,Type) inline Type operator Symbol(const Type& mdt){\
	Type res;\
	res.data = data Symbol mdt.data;\
	return res;\
	}\
// = += -=
#define OPER_FUN_MDREF(Symbol,Type) inline Type& operator Symbol(const Type& mdt){\
	data Symbol mdt.data; \
	return *this;\
	}\
//
#define OPER_FUN_OTHER(Symbol,Type1,Type2) inline Type1 operator Symbol(const Type2& rdata) {\
	Type1 res;\
	res.data = data Symbol (rdata * S_accuracy);\
	return res;\
	}\
//
#define MDF_MDD(Symbol,Type) static inline MDdouble operator Symbol(MDfloat left, const Type& rdata) {\
	MDdouble res(left);\
	res Symbol= rdata;\
	return res;\
	}\

贴整个mdfloat源码出来

struct MDdouble;
struct MDfloat {
protected:
	int data;
public:
	MDfloat(double d) {
		data = d * S_accuracy;
	}
	MDfloat(float d) {
		data = d * S_accuracy;
	}
	MDfloat(int d = 0) {
		data = d * S_accuracy;
	}
	MDfloat(char d) {
		data = d * S_accuracy;
	}
	MDfloat(long long d) {
		data = d * S_accuracy;
	}
	MDfloat(const MDdouble& d);

	OPER_FUN_BOOL(==,MDfloat)
	OPER_FUN_BOOL(!=, MDfloat)
	OPER_FUN_BOOL(<,MDfloat)
	OPER_FUN_BOOL(<=, MDfloat)
	OPER_FUN_BOOL(>, MDfloat)
	OPER_FUN_BOOL(>=, MDfloat)

	OPER_FUN_OTHER(+, MDfloat, int)
	OPER_FUN_OTHER(-, MDfloat, int)
	inline MDfloat operator *(const int& rdata) {
		MDfloat res;
		res.data = data * rdata;
		return res;
	}
	inline MDfloat operator /(const int& rdata) {
		if (rdata == 0) {
			throw "MDfloat rdata div 0";
		}
		MDfloat res; 
		res.data = data / rdata;
		return res;
	}

	OPER_FUN_MD(+, MDfloat);
	OPER_FUN_MD(-, MDfloat);
	inline MDfloat operator *(const MDfloat& mdt) {
		MDfloat res;
		res.data = data * mdt.data / S_accuracy;
		return res;
	}
	inline MDfloat operator /(const MDfloat& mdt) {
		if (mdt.data == 0) {
			throw "MDfloat div 0";
		}
		return MDfloat(data / mdt.data);
	}
	
	OPER_FUN_MDREF(=, MDfloat)
	OPER_FUN_MDREF(+=, MDfloat)
	OPER_FUN_MDREF(-=, MDfloat)
	inline MDfloat& operator *=(const MDfloat& mdt) {
		data = data * mdt.data / S_accuracy;
		return *this;
	}
	inline MDfloat& operator /=(const MDfloat& mdt) {
		if (mdt.data == 0) {
			throw "MDfloat div 0";
		}
		data = data / mdt.data * S_accuracy;
		return *this;
	}
	inline operator float() {
		return data / (float)S_accuracy;
	}
	inline int getdata() const {
		return data;
	}
};

以下代码是为了非mdfloat数值和mdfloat相运算

OPER_FUN_OTHER(+, MDfloat, int)
OPER_FUN_OTHER(-, MDfloat, int)
inline MDfloat operator *(const int& rdata) {
	MDfloat res;
	res.data = data * rdata;
	return res;
}
inline MDfloat operator /(const int& rdata) {
	if (rdata == 0) {
		throw "MDfloat rdata div 0";
	}
	MDfloat res; 
	res.data = data / rdata;
	return res;
}

以下代码是为了得到真实的float值

inline operator float() {
	return data / (float)S_accuracy;
}
//MDfloat遇到long long,要转成MDdouble处理
MDF_MDD(+, long long);
MDF_MDD(-, long long);
MDF_MDD(*, long long);
MDF_MDD(/, long long);

就这样实现了,也贴一下测试代码

void OnFunc_MDfloat1() {
 MyDog::S_accuracy = 100;
 MDfloat f = 0.01;
 MDfloat f2 = 0.02;
 auto f3 = f2 * f;
 cout << f3 << endl;
 f2 += f;
 cout << f2 << endl;
}
void OnFunc_MDfloat2() {
 int i = 10;
 MDfloat f2 = 0.02;
 f2 += i;
 cout << (float)f2 << endl;
 auto f3 = f2 + i;
 cout << f3 << endl;
 f3 = i + f2;
 cout << f3 << endl;
}
void OnFunc_MDfloat3() {
 long long i = 10;
 MDfloat f2 = 0.02;
 cout << i * f2 << endl;//=>i*(float)f2
 cout << f2 * i << endl;//=>MDfloat operator *(const int& rdata)
 auto f4 = f2 * i;
 f2 = f4;
 cout << f2 + i + 10 << endl;
 int ii = 11;
 cout << ii * f2 << endl;
 cout << f2 * ii << endl;
 auto f3 = i + f2;
 cout << f3 << endl;
 f3 = f2 + ii + 10;
 cout << f3 << endl;
 f2 = i;
 cout << f2 << endl;
 
}

虽然有这样的报错:

但对C++来说,可以不管的...我window和linux都运行过测试代码.


MyDog--前言和目录(附源码链接)-CSDN博客

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值