c++ 分数运算简单封装

简介

把分数的一些基本操作封装到了一个类里,支持输入,输出,乘法,加法,约分和取倒数等操作,分数间的运算也都已经重载好了,可以直接使用

Code

#include<iostream>
template<typename ll=long long>
class Frac
{
	private:
		ll abs(const ll& x)const{return x<0?-x:x;}
		ll gcd(const ll& x,const ll& y)const{return y?gcd(y,x%y):x;}
		Frac reduce()
		{
			bool flag=0;
			if(a<0&&b<0) a=-a,b=-b;
			if(a<0) a=-a,flag=1;
			if(b<0) b=-b,flag=1;
			ll ggcd=gcd(a,b);
			a/=ggcd;
			b/=ggcd;
			if(flag) a=-a;
			return *this;
		}
		void swap(){std::swap(a,b);}
		Frac _swap(const Frac& t)const{return Frac(t.b,t.a);}
		ll FastPow(ll x,ll p,ll mod)const
		{
			ll ans=1,bas=x;
			for(;p;bas=bas*bas%mod,p>>=1)
				if(p&1) ans=ans*bas%mod;
			return ans;
		}
	public:
		ll a,b;
		Frac(ll A=0,ll B=1){a=A,b=B;}
		void show()const{std::cerr<<'['<<a<<'/'<<b<<"]
";}
		ll to_int(const ll& mod=998244353)const{return a*FastPow(b,mod-2,mod)%mod;}
		Frac abs()const{return Frac(abs(a),abs(b));}
		Frac operator =(const Frac& t){return a=t.a,b=t.b,t;}
		bool operator ==(const Frac& t)const{Frac A(*this),B(t);return (A.reduce().a==B.reduce().a)&&(A.b==B.b);}
		bool operator !=(const Frac& t)const{Frac A(*this),B(t);return (A.a!=B.a)||(A.b!=B.b);}
		bool operator >(const Frac& t)const{Frac A(*this),B(t);ll ggcd=gcd(A.reduce().b,B.reduce().b);return B.b/ggcd*A.a>A.b/ggcd*B.a;}
		bool operator <(const Frac& t)const{Frac A(*this),B(t);ll ggcd=gcd(A.reduce().b,B.reduce().b);return B.b/ggcd*A.a<A.b/ggcd*B.a;}
		bool operator >=(const Frac& t)const{Frac A(*this),B(t);ll ggcd=gcd(A.reduce().b,B.reduce().b);return B.b/ggcd*A.a>=A.b/ggcd*B.a;}
		bool operator <=(const Frac& t)const{Frac A(*this),B(t);ll ggcd=gcd(A.reduce().b,B.reduce().b);return B.b/ggcd*A.a<=A.b/ggcd*B.a;}
		Frac operator +(const Frac& t)const{ll ggcd=gcd(b,t.b);return Frac(b/ggcd*t.a+t.b/ggcd*a,b/ggcd*t.b).reduce();}
		Frac operator +=(const Frac& t){return *this=*this+t;}
		Frac operator *(const Frac& t)const{return Frac(a*t.a,b*t.b).reduce();}
		Frac operator *=(const Frac& t){return *this=*this*t;}
		Frac operator -(const Frac& t)const{return (*this+Frac(-t.a,t.b)).reduce();}
		Frac operator -=(const Frac& t){return *this=*this-t;}
		Frac operator /(const Frac& t)const{return (t._swap(t)*(*this)).reduce();}
		Frac operator /=(const Frac& t){return *this=*this/t;}
		Frac operator -()const{return Frac(-a,b);}
};

使用方法

把这一坨代码放在你的代码开头,就可以使用了,下面来举几个例子

Frac<long long>a(1,2);//定义一个值为1/2,分子分母均为longlong类型的分数变量a 
a.show();//调试输出a
Frac<long long>b(1,3);//定义一个值为1/3,分子分母均为longlong类型的分数变量b
(a+b).show();//调试输出a+b的值
a*=b;//让a=a*b
std::cerr<<a.to_int()<<'
';//调试输出a在模998244353意义下的值
a=-a;//取反a
std::cerr<<(a==Frac<long long>(-2,12))<<'
';//调试输出a是否等于-2/12
a.abs().show();//输出a的绝对值 

注意事项:类型尽量定义为long long类型,否则可能会出现未知错误,因为int可能会导致溢出,而unsigned类型会导致负数溢出

原文地址:https://www.cnblogs.com/cmy-blog/p/fraction.html