简介
把分数的一些基本操作封装到了一个类里,支持输入,输出,乘法,加法,约分和取倒数等操作,分数间的运算也都已经重载好了,可以直接使用
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类型会导致负数溢出