C++实现一个分数模板类的头文件

使用C++语言自己实现了一个分数类。
支持分数加减乘除四则运算,输入输出操作,分数大小比较等基本功能。支持用模板自定义表示分子和分母的整数类型。
语法严谨,缩进适当,注释简洁。

/** 有理数模板类实现文件 Rational.h
 ** @obertys V5.0 2023/07/21
 **
 ** 有理数实现为整数与整数之比,如1\2、-9\4等
 ** 支持有理数加减乘除四则运算,输入输出操作,有理数大小比较等基本功能
 ** 注意在输入输出中,分数线表示为反斜杠'\\'
 **
 ** 模板类型integer必须有符号(支持负数)且支持基本运算,不建议将浮点数作为模板类型参数
 **/
#include<iostream>

/*友元模板函数前置声明*/
template<typename integer> class Rational;
template<typename integer> std::istream& operator>>(std::istream& input,Rational<integer>& fraction);
template<typename integer> std::ostream& operator<<(std::ostream& output,const Rational<integer>& fraction);
template<typename integer> std::string& operator>>(std::string& input,Rational<integer>& fraction);
template<typename integer> std::string& operator<<(std::string& output,const Rational<integer>& fraction);
template<typename integer> bool operator==(const Rational<integer>& fractionA,const Rational<integer>& fractionB);
template<typename integer> bool operator<(const Rational<integer>& fractionA,const Rational<integer>& fractionB);
template<typename integer> bool operator>(const Rational<integer>& fractionA,const Rational<integer>& fractionB);
template<typename integer> Rational<integer> operator+(const Rational<integer>& fractionA,const Rational<integer>& fractionB);
template<typename integer> Rational<integer> operator-(const Rational<integer>& fractionA,const Rational<integer>& fractionB);
template<typename integer> Rational<integer> operator*(const Rational<integer>& fractionA,const Rational<integer>& fractionB);
template<typename integer> Rational<integer> operator/(const Rational<integer>& fractionA,const Rational<integer>& fractionB);

/*有理数模板类定义*/
template<typename integer>
class Rational
{
public:
	/*异常类型*/
	struct DivideByZero {};	//除以0异常类

	/*流输入输出运算符*/
	/*可输入一个整数或一个整数除以另一个整数的形式,输入的正号或负号应总是在第一个整数之前*/
	/*输入示例:-1 0 25 8\3 -9\51*/
	/*输出为一个整数,或一个整数除以另一个整数的形式*/
	/*输出示例:-1 0 25 8\3 -9\51*/
	friend std::istream& operator>> <>(std::istream& input,Rational& fraction);
	friend std::ostream& operator<< <>(std::ostream& output,const Rational& fraction);

	/*字符串输入输出运算符(流输入输出的字符串版本)*/
	friend std::string& operator>> <>(std::string& input,Rational& fraction);
	friend std::string& operator<< <>(std::string& output,const Rational& fraction);

	/*大小比较运算符*/
	friend bool operator== <>(const Rational& fractionA,const Rational& fractionB);
	friend bool operator==(const Rational& fractionA,const integer& fractionB)
	{
		return fractionA==Rational(fractionB);
	}
	friend bool operator==(const integer& fractionA,const Rational& fractionB)
	{
		return Rational(fractionA)==fractionB;
	}

	friend bool operator!=(const Rational& fractionA,const Rational& fractionB)
	{
		return !(fractionA==fractionB);
	}
	friend bool operator!=(const integer& fractionA,const Rational& fractionB)
	{
		return !(fractionA==fractionB);
	}
	friend bool operator!=(const Rational& fractionA,const integer& fractionB)
	{
		return !(fractionA==fractionB);
	}

	friend bool operator< <>(const Rational& fractionA,const Rational& fractionB);
	friend bool operator<(const integer& fractionA,const Rational& fractionB)
	{
		return Rational(fractionA)<fractionB;
	}
	friend bool operator<(const Rational& fractionA,const integer& fractionB)
	{
		return fractionA<Rational(fractionB);
	}

	friend bool operator<=(const Rational& fractionA,const Rational& fractionB)
	{
		return !(fractionA>fractionB);
	}
	friend bool operator<=(const integer& fractionA,const Rational& fractionB)
	{
		return !(fractionA>fractionB);
	}
	friend bool operator<=(const Rational& fractionA,const integer& fractionB)
	{
		return !(fractionA>fractionB);
	}

	friend bool operator> <>(const Rational& fractionA,const Rational& fractionB);
	friend bool operator>(const integer& fractionA,const Rational& fractionB)
	{
		return Rational(fractionA)>fractionB;
	}
	friend bool operator>(const Rational& fractionA,const integer& fractionB)
	{
		return fractionA>Rational(fractionB);
	}

	friend bool operator>=(const Rational& fractionA,const Rational& fractionB)
	{
		return !(fractionA<fractionB);
	}
	friend bool operator>=(const integer& fractionA,const Rational& fractionB)
	{
		return !(fractionA<fractionB);
	}
	friend bool operator>=(const Rational& fractionA,const integer& fractionB)
	{
		return !(fractionA<fractionB);
	}

	/*一元运算符+-*/
	friend Rational operator+(const Rational& fraction)
	{
		return fraction;
	}
	friend Rational operator-(const Rational& fraction)
	{
		return Rational(-fraction.numerator,fraction.denominator);
	}

	/*二元运算符+,-,*,/*/
	friend Rational operator+ <>(const Rational& fractionA,const Rational& fractionB);
	friend Rational operator- <>(const Rational& fractionA,const Rational& fractionB);
	friend Rational operator* <>(const Rational& fractionA,const Rational& fractionB);
	friend Rational operator/ <>(const Rational& fractionA,const Rational& fractionB);

	friend Rational operator+(const integer& fractionA,const Rational& fractionB)
	{
		return Rational(fractionA)+fractionB;
	}
	friend Rational operator-(const integer& fractionA,const Rational& fractionB)
	{
		return Rational(fractionA)-fractionB;
	}
	friend Rational operator*(const integer& fractionA,const Rational& fractionB)
	{
		return Rational(fractionA)*fractionB;
	}
	friend Rational operator/(const integer& fractionA,const Rational& fractionB)
	{
		return Rational(fractionA)/fractionB;
	}
	friend Rational operator+(const Rational& fractionA,const integer& fractionB)
	{
		return fractionA+Rational(fractionB);
	}
	friend Rational operator-(const Rational& fractionA,const integer& fractionB)
	{
		return fractionA-Rational(fractionB);
	}
	friend Rational operator*(const Rational& fractionA,const integer& fractionB)
	{
		return fractionA*Rational(fractionB);
	}
	friend Rational operator/(const Rational& fractionA,const integer& fractionB)
	{
		return fractionA/Rational(fractionB);
	}

	/*构造函数*/
	Rational(void):numerator(0),denominator(1) {}	//有理数0
	Rational(integer Numberator,integer Denominator);	//有理数Numberator/Denominator

	/*转换函数*/
	Rational(integer wholeNumber):numerator(wholeNumber),denominator(1) {}	//有理数wholeNumber
	template<typename T> T toDecimal(void) const	//返回分数的小数形式
	{
		return static_cast<T>(numerator)/static_cast<T>(denominator);
	}

	/*取值/赋值函数*/
	integer Numerator(void) const	//返回分子
	{
		return numerator;
	}
	integer Denominator(void) const	//返回分母
	{
		return denominator;
	}
	void Numerator(integer Numerator_);	//设置分子
	void Denominator(integer Denominator_);	//设置分母

	/*一元运算符+=,-=,*=,/=*/
	void operator+=(const Rational& fraction)
	{
		*this=*this+fraction;
		return;
	}
	void operator-=(const Rational& fraction)
	{
		*this=*this-fraction;
		return;
	}
	void operator*=(const Rational& fraction)
	{
		*this=*this*fraction;
		return;
	}
	void operator/=(const Rational& fraction)
	{
		if(fraction==0)
			throw DivideByZero();
		*this=*this/fraction;
		return;
	}

	void operator+=(const integer& fraction)
	{
		*this=*this+fraction;
		return;
	}
	void operator-=(const integer& fraction)
	{
		*this=*this-fraction;
		return;
	}
	void operator*=(const integer& fraction)
	{
		*this=*this*fraction;
		return;
	}
	void operator/=(const integer& fraction)
	{
		if(fraction==0)
			throw DivideByZero();
		*this=*this/fraction;
		return;
	}

private:
	/*数据变量*/
	integer numerator;	//分子
	integer denominator;	//分母

	/*辅助成员函数*/
	void reduction(void);	//约分

};

/*辅助函数*/
template<typename integer> static integer gcd_lcm(register integer x,register integer y,char op)	//op为'G'返回x,y最大公约数,为'L'返回x,y最小公倍数
{
	//x的符号,y的符号,gcd的符号,lcm的符号:正正正正,负负负负,正负正负,负正负正
	integer temp=x*y,z;
	while(y)	//辗转反除
	{
		z=x%y;
		x=y;
		y=z;
	}
	switch(op)
	{
	case 'G':
		return x;
	case 'L':
		return temp/x;
	default:
		return 0;
	}
}
template<typename integer> inline char sing(integer a)	//返回a的符号
{
	return a<0?'-':'+';
}
template<typename integer> inline integer abs(integer a)	//返回a的绝对值
{
	return a<0?-a:a;
}

/*有理数模板类成员函数、友元函数实现*/
template<typename integer> Rational<integer>::Rational(integer Numberator,integer Denominator):numerator(Numberator),denominator(Denominator)	//有理数Numberator/Denominator
{
	reduction();
}

template<typename integer> void Rational<integer>::reduction(void)	//约分
{
	integer num_gcd=gcd_lcm(numerator,denominator,'G');	//求最大公约数
	numerator/=num_gcd,denominator/=num_gcd;	//约分赋值
	if(denominator<0)
		numerator=-numerator,denominator=-denominator;
	else if(denominator==0)
		throw DivideByZero();
}
template<typename integer> void Rational<integer>::Numerator(integer Numerator_)	//设置分子
{
	numerator=Numerator_;
	return;
}
template<typename integer> void Rational<integer>::Denominator(integer Denominator_)	//设置分母
{
	if(Denominator_<0)
		numerator=-numerator,denominator=-Denominator_;
	else
		denominator=Denominator_;
	return;
}

template<typename integer> std::istream& operator>>(std::istream& input,Rational<integer>& fraction)	//流输入
{
	input>>fraction.numerator;
	if(input.peek()=='\\')
	{
		input.ignore(1);
		input>>fraction.denominator;
		fraction.reduction();
	}
	else
		fraction.denominator=1;
	return input;
}
template<typename integer> std::ostream& operator<<(std::ostream& output,const Rational<integer>& fraction)	//流输出
{
	output<<fraction.numerator;
	if(fraction.denominator!=1)
		output<<'\\'<<fraction.denominator;
	return output;
}
template<typename integer> std::string& operator>>(std::string& input,Rational<integer>& fraction)	//字符串输入
{
	char* ptr;
	const char* input_str=input.c_str();
	fraction.numerator=strtoll(input_str,&ptr,10);
	if(*ptr=='\\')
	{
		fraction.denominator=strtoll(ptr+1,&ptr,10);
		fraction.reduction();
	}
	else
		fraction.denominator=1;
	input.erase(0,ptr-input_str);	//擦除字符串中提取的分数
	return input;
}
template<typename integer> std::string& operator<<(std::string& output,const Rational<integer>& fraction)	//字符串输出
{
	output+=to_string(fraction.numerator);	//后缀分子至字符串
	if(fraction.denominator!=1)
		output+='\\'+to_string(fraction.denominator);
	return output;
}

template<typename integer> bool operator==(const Rational<integer>& fractionA,const Rational<integer>& fractionB)
{
	return fractionA.numerator*fractionB.denominator==fractionA.denominator*fractionB.numerator;
}
template<typename integer> bool operator<(const Rational<integer>& fractionA,const Rational<integer>& fractionB)
{
	return fractionA.numerator*fractionB.denominator<fractionA.denominator*fractionB.numerator;
}
template<typename integer> bool operator>(const Rational<integer>& fractionA,const Rational<integer>& fractionB)
{
	return fractionA.numerator*fractionB.denominator>fractionA.denominator*fractionB.numerator;
}

template<typename integer> Rational<integer> operator+(const Rational<integer>& fractionA,const Rational<integer>& fractionB)
{
	Rational<integer> ret;	//A+B
	ret.denominator=gcd_lcm(fractionA.denominator,fractionB.denominator,'L');	//分母为最小公倍数
	ret.numerator=fractionA.numerator*(ret.denominator/fractionA.denominator)+fractionB.numerator*(ret.denominator/fractionB.denominator);	//分子为A,B分子通分后的和
	ret.reduction();	//约分
	return ret;
}
template<typename integer> Rational<integer> operator-(const Rational<integer>& fractionA,const Rational<integer>& fractionB)
{
	Rational<integer> ret;	//A-B
	ret.denominator=gcd_lcm(fractionA.denominator,fractionB.denominator,'L');	//分母为最小公倍数
	ret.numerator=fractionA.numerator*(ret.denominator/fractionA.denominator)-fractionB.numerator*(ret.denominator/fractionB.denominator);	//分子为A,B分子通分后的差
	ret.reduction();	//约分
	return ret;
}
template<typename integer> Rational<integer> operator*(const Rational<integer>& fractionA,const Rational<integer>& fractionB)
{
	Rational<integer> ret;
	Rational<integer> A_temp(fractionA.numerator,fractionB.denominator);
	Rational<integer> B_temp(fractionB.numerator,fractionA.denominator);
	ret.numerator=A_temp.numerator*B_temp.numerator;	//分子相乘得分子
	ret.denominator=A_temp.denominator*B_temp.denominator;	//分母相乘得分母
	return ret;
}
template<typename integer> Rational<integer> operator/(const Rational<integer>& fractionA,const Rational<integer>& fractionB)
{
	Rational<integer> B_temp(fractionB.denominator,fractionB.numerator);	//A/B=A*(1/B);
	if(B_temp.denominator==0)	//除数为0
		throw typename Rational<integer>::DivideByZero();
	return fractionA*B_temp;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值