一种不会丢失精度的分数表示法
众所周知,C++ 中就算是精度最高的浮点数 long double
也会存在可观的精度丢失的问题,那么我们该如何解决这个问题呢?高精度浮点数又显得过于夸张繁琐。
何不想个折中的法子?
于是,我们想到了一种办法,用 long long
分别表示分母和分子!
而我们在进行分数运算的时候,就可以模拟人工手算分数的办法来操作,比如说
之后再求gcd约分即可
而比较两个分数的方法也很简单
坑点:
- 有负数时,比较大小时要分类讨论!
- 约分时gcd不要传负数进去,概率出玄学错误!
- 分母的负号一定要传给分子,不然 -114514/1919810 就会输出成 114514/-1919810 !
- 分母为1或者分子为0时,就不用输出分数线了!(这项看情况,有些题目强制分数形式输出)
struct Fraction{
LL up/*分子*/,down/*分母*/;
Fraction(){}
Fraction(LL a,LL b){
up=a;down=b;
reduction();
}
inline Fraction reduction(){
if(down<0){
up=-up;
down=-down;
}
LL div=__gcd(abs(up),abs(down));
up/=div;
down/=div;
return *this;
}
inline void flip(){//取倒数
swap(up,down);
}
inline void print(){
reduction();
if(down==1) cout<<up;
else cout<<up<<'/'<<down;
}
friend std::ostream & operator << (std::ostream &os,Fraction x){
x.reduction();
if(x.down==1) os<<x.up;
else os<<x.up<<'/'<<x.down;
return os;
}
};
inline Fraction operator + (const Fraction& x,const Fraction& y){
Fraction res;
res.up=x.up*y.down+x.down*y.up;
res.down=x.down*y.down;
res.reduction();
return res;
}
inline Fraction operator - (const Fraction& x,const Fraction& y){
Fraction res;
res.up=x.up*y.down-x.down*y.up;
res.down=x.down*y.down;
res.reduction();
return res;
}
inline Fraction operator * (const Fraction& x,const Fraction& y){
Fraction res;
res.up=x.up*y.up;
res.down=x.down*y.down;
res.reduction();
return res;
}
inline Fraction operator / (const Fraction& x,const Fraction& y){
Fraction res;
res.up=x.up*y.down;
res.down=x.down*y.up;
res.reduction();
return res;
}
inline bool operator < (const Fraction& x,const Fraction& y){
int tmp=(x.down<0)+(y.down<0);//判断负数个数
return tmp%2==0 ? (x.up*y.down<x.down*y.up) : (x.up*y.down>x.down*y.up);//压行,负数为奇数个变号,反之不变
}
inline bool operator <= (const Fraction& x,const Fraction& y){
int tmp=(x.down<0)+(y.down<0);
return tmp%2==0 ? (x.up*y.down<=x.down*y.up) : (x.up*y.down>=x.down*y.up);
}
inline bool operator > (const Fraction& x,const Fraction& y){
int tmp=(x.down<0)+(y.down<0);
return tmp%2==0 ? (x.up*y.down>x.down*y.up) : (x.up*y.down<x.down*y.up);
}
inline bool operator >= (const Fraction& x,const Fraction& y){
int tmp=(x.down<0)+(y.down<0);
return tmp%2==0 ? (x.up*y.down>=x.down*y.up) : (x.up*y.down<=x.down*y.up);
}
inline bool operator == (const Fraction& x,const Fraction& y){
return x.up*y.down==x.down*y.up;
}
inline bool operator != (const Fraction& x,const Fraction& y){
return x.up*y.down!=x.down*y.up;
}
本文作者:MessageBoxA
本文链接:https://www.cnblogs.com/SkyNet-PKN/p/17135648.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步