分数模板(C++模板)

貌似没什么用。。。没有多少毒瘤题要输出分数吧。。。

update:真的有,而且在NOIP模拟赛里出现了!写double的卡精度到怀疑人生!

可以套个兼容性比较好的高精度模板进来。

#include<bits/stdc++.h>
using namespace std;
namespace FlashHu{
#define RG register
#define I inline
#define R RG frac
#define OutputFormat 0
	template<typename T>
	T gcd(RG T a,RG T b){
		return b?gcd(b,a%b):a;
	}
	template<typename T>
	struct frac{
		T a,b;
		
		//initializations
		I frac(){
			a=(T)0;b=(T)1;
		}
		I frac(RG T x){
			a=x;b=(T)1;
		}
		I frac(RG T x,RG T y){
			a=x;b=y;
			this->init();
		}
		I void init(){
			assert(b);
			if(b<0)a=-a,b=-b;
			this->reduction();
		}
		I frac&operator=(RG T x){
			a=x;b=1;
			return*this;
		}
		I double to_double(){
			return(double)a/b;
		}
		
		//arithmetic operation
		I void reduction(){
			RG T g=gcd(abs(a),b);
			a/=g;b/=g;
		}
		I frac inv(){
			assert(a);
			return(frac){b,a};
		}
		I frac operator-(){
			return(frac){-a,b};
		}
		I frac&operator++(){
			a+=b;
			return*this;
		}
		I frac&operator--(){
			a-=b;
			return*this;
		}
		I frac&operator+=(R x){
			RG T g=gcd(b,x.b);
			a=b/g*x.a+x.b/g*a;(b/=g)*=x.b;
			this->reduction();
			return*this;
		}
		I frac&operator-=(R x){
			return*this+=-x;
		}
		I frac&operator*=(R x){
			RG T g1=gcd(abs(a),x.b),g2=gcd(abs(x.a),b);
			(a/=g1)*=x.a/g2;(b/=g2)*=x.b/g1;
			return*this;
		}
		I frac&operator/=(R x){
			return*this*=x.inv();
		}
		I frac friend operator+(R x,R y){
			RG T g=gcd(x.b,y.b);
			x=(frac){x.b/g*y.a+y.b/g*x.a,x.b/g*y.b};
			x.reduction();
			return x;
		}
		I frac friend operator-(R x,R y){
			return x+-y;
		}
		I frac friend operator*(R x,R y){
			RG T g1=gcd(abs(x.a),y.b),g2=gcd(abs(y.a),x.b);
			(x.a/=g1)*=y.a/g2;(x.b/=g2)*=y.b/g1;
			return x;
		}
		I frac friend operator/(R x,R y){
			return x*y.inv();
		}
		
		//logic operations
		I bool operator!(){
			return!a;
		}
		I bool friend operator&&(R x,R y){
			return x.a&&y.a;
		}
		I bool friend operator||(R x,R y){
			return x.a||y.a;
		}
		I bool friend operator==(R x,R y){
			return x.a==y.a&&x.b==y.b;
		}
		I bool friend operator!=(R x,R y){
			return x.a!=y.a||x.b!=y.b;
		}
#define logop(op)												\
		I bool friend operator op(R x,R y){						\
			return (x+-y).a op 0;								\
		}
		logop(<);logop(>);logop(<=);logop(>=);
#undef logop
		
		//input and output
		I friend istream&operator>>(RG istream&is,R&x){
			x=0;
			static string s;is>>s;
			RG int pos=s.find_first_of('/');
			if(~pos){
				s[pos]=' ';
				istringstream(s)>>x.a>>x.b;
				x.init();
			}
			else istringstream(s)>>x.a;
			return is;
		}
		I friend ostream&operator<<(RG ostream&os,R x){
			os<<x.a;
			if(OutputFormat||x.b!=1)os<<'/'<<x.b;
			return os;
		}
	};
#undef RG
#undef I
#undef R
#undef OutputFormat
}
posted @ 2018-09-13 18:07  Flash_Hu  阅读(857)  评论(2编辑  收藏  举报