簡介
把分數的一些基本操作封裝到了一個類里,支持輸入,輸出,乘法,加法,約分和取倒數等操作,分數間的運算也都已經重載好了,可以直接使用
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<<"]\n";}
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()<<'\n';//調試輸出a在模998244353意義下的值
a=-a;//取反a
std::cerr<<(a==Frac<long long>(-2,12))<<'\n';//調試輸出a是否等於-2/12
a.abs().show();//輸出a的絕對值
注意事項:類型盡量定義為long long類型,否則可能會出現未知錯誤,因為int可能會導致溢出,而unsigned類型會導致負數溢出