我们都知道,C++中就算是精度最高的浮点数long double也会存在精度丢失的问题,那么我们该如何解决这个问题呢?高精度浮点数又显得过于夸张繁琐
![](/i/ll/?i=3f5d47f6e2ba4a48a9ce410be39bd218.png =300x300)
于是,我们想到了一种办法,用long long分别表示分母和分子!
而我们在进行分数运算的时候,就可以模拟人工手算分数的办法来操作,比如说
之后再求gcd约分即可
而比较两个分数的方法也很简单
你以为这就完了吗?
不!
坑点:
- 有负数时,比较大小时要分类讨论!
- 约分时gcd不要传负数进去,概率出玄学错误!
- 输出时分母的负号一定要传给分子,不然 -114514/1919810 就会输出成 114514/-1919810 !
- 分母为1或者分子为0时,就不用输出分数线了!(这项看情况,有些题目强制分数形式输出)
上代码!
#include<bits/stdc++.h>
using namespace std;
using LL = long long;
struct Fraction{
LL up/*分子*/,down/*分母*/;
inline void reduction(){//约分
if(up<0&&(down<0 || down<0)){//负号可以约掉 或 需要把分母符号移到分子
up=-up;
down=-down;
}
LL div=__gcd(abs(up),abs(down));//gcd最好加个绝对值不然可能爆玄学错误
up/=div;
down/=div;
}
inline void output(){//输出
reduction();//再次约分确保安全
cout<<up<<'/'<<down;
}
inline void reverse(){//取倒数
swap(up,down);
}
Fraction operator + (const Fraction &x){
Fraction res;
res.up=up*x.down+down*x.up;
res.down=down*x.down;
res.reduction();
return res;
}
Fraction operator - (const Fraction &x){
Fraction res;
res.up=up*x.down-down*x.up;
res.down=down*x.down;
res.reduction();
return res;
}
Fraction operator * (const Fraction &x){
Fraction res;
res.up=up*x.up;
res.down=down*x.down;
res.reduction();
return res;
}
Fraction operator / (const Fraction &x){
Fraction res;
res.up=up*x.down;
res.down=down*x.up;
res.reduction();
return res;
}
inline bool operator < (const Fraction &x){
int tmp=(down<0)+(x.down<0);//判断负数个数的简单写法,总不可能4种情况if一遍吧
return tmp%2==0 ? (up*x.down<down*x.up) : (up*x.down>down*x.up);//极致压行,负数为奇数个变号,反之不变
}
inline bool operator <= (const Fraction &x){
int tmp=(down<0)+(x.down<0);
return tmp%2==0 ? (up*x.down<=down*x.up) : (up*x.down>=down*x.up);
}
inline bool operator > (const Fraction &x){
int tmp=(down<0)+(x.down<0);
return tmp%2==0 ? (up*x.down>down*x.up) : (up*x.down<down*x.up);
}
inline bool operator >= (const Fraction &x){
int tmp=(down<0)+(x.down<0);
return tmp%2==0 ? (up*x.down>=down*x.up) : (up*x.down<=down*x.up);
}
inline bool operator == (const Fraction &x){
return up*x.down==down*x.up;
}
inline bool operator != (const Fraction &x){
return up*x.down!=down*x.up;
}
};
int main(){
ios::sync_with_stdio(false);
return 0;
}
/*
#include<bits/stdc++.h>
#define LD long double
using namespace std;
const int MAXN=2e5+5;
const LD eps=(LD)1.0e-30;
typedef pair<int,int> pii;
int n;
pii stand,inp[MAXN],ans;
LD mindelta=LDBL_MAX,mink,k,delta,stdk;
inline LD lfabs(LD x){
if(x>=0) return x;
else return -x;
}
int main(){
ios::sync_with_stdio(false);
cin>>n;
cin>>stand.first>>stand.second;
stdk=(LD)stand.first/(LD)stand.second;
for(int i=1;i<=n;i++){
cin>>inp[i].first>>inp[i].second;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i==j) continue;
k=((LD)abs(inp[i].second-inp[j].second))/((LD)abs(inp[i].first-inp[j].first));
delta=lfabs(k-stdk);
if(delta<mindelta || (lfabs(delta-mindelta)<=eps && k<mink)){
mink=k;
mindelta=delta;
ans={abs(inp[i].second-inp[j].second),abs(inp[i].first-inp[j].first)};
}
}
}
int gcd=__gcd(ans.first,ans.second);
cout<<ans.first/gcd<<'/'<<ans.second/gcd<<endl;
return 0;
}
*/
标签:分数,down,LD,int,up,long,表示法,丢失,stand
From: https://www.cnblogs.com/SkyNet-PKN/p/17135648.html