1. 程式人生 > >GCD LCM 最大公約數 最小公倍數 分數模板 (防溢出優化完成)

GCD LCM 最大公約數 最小公倍數 分數模板 (防溢出優化完成)

IV 完成 lcm \n 最大公約數 cmp spa 運算 print

自己寫的一個分數模板,在運算操作時進行了防溢出的優化:

ll gcd(ll a, ll b) {
    return b ? gcd(b, a%b) : a;
}
 
ll lcm(ll a, ll b) {
    return a / gcd(a,b) * b;
}
 
struct divi {
    ll a = 0,b = 1;
};
 
divi simdiv(divi a) {
    ll i;
    divi divn = a;
    ll k = gcd(a.a,a.b);
    divn.a /= k;
    divn.b /= k;
    if(divn.b < 0
) { divn.a = -divn.a; divn.b = -divn.b; } return divn; } divi plusdiv(divi i,divi j) { divi a = simdiv(i); divi b = simdiv(j); divi dn; dn.b = lcm(a.b,b.b); dn.a = a.a*(dn.b/a.b)+b.a*(dn.b/b.b); return simdiv(dn); } divi minusdiv(divi i,divi j) { divi a
= simdiv(i); divi b = simdiv(j); divi dn; dn.b = lcm(a.b,b.b); dn.a = a.a*(dn.b/a.b)-b.a*(dn.b/b.b); return simdiv(dn); } divi muldiv(divi i, divi j) { divi a = simdiv(i); divi b = simdiv(j); divi dn; ll chu1 = gcd(a.a,b.b); ll chu2 = gcd(a.b,b.a); dn.b = (a.b/chu2) * (b.b/chu1); dn.a
= (a.a/chu1) * (b.a/chu2); return simdiv(dn); } divi divdiv(divi i,divi j) { divi a = simdiv(i); divi b = simdiv(j); divi dn; ll chu1 = gcd(a.a,b.a); ll chu2 = gcd(a.b,b.b); dn.b = (a.b / chu2) * (b.a / chu1); dn.a = (a.a / chu1) * (b.b / chu2); return simdiv(dn); } int cmpdiv(divi i,divi j) { //a>b返回1, a=b返回0, a<b返回-1, 無法比較返回INF divi a = simdiv(i); divi b = simdiv(j); if(a.b == 0 || b.b == 0) { if(a.b == 0 && b.b == 0) return INF; else { if(a.b == 0) { if(a.a > 0) return 1; if(a.a < 0) return -1; if(a.a == 0) return INF; } else { if(b.b == 0) { if(b.a > 0) return -1; if(b.a < 0) return 1; if(b.a == 0) return INF; } } } } else { ll di = lcm(a.b,b.b); ll a1 = a.a * (di / a.b); ll a2 = b.a * (di / b.b); if(a1 > a2) return 1; if(a1 == a2) return 0; if(a1 < a2) return -1; } } double valueofdiv(divi a) { if(a.a == 0) return 0; if(a.b == 0) { if(a.a >= 0) return (double)INF; if(a.a < 0) return -(double)INF; } return (double)a.a/(double)a.b; }

測試代碼:

divi a,b;
while(1==1) {
    scanf("%lld%lld",&a.a,&a.b);
    scanf("%lld%lld",&b.a,&b.b);
    printf("+: %lld/%lld\n",plusdiv(a,b).a,plusdiv(a,b).b);
    printf("-: %lld/%lld\n",minusdiv(a,b).a,minusdiv(a,b).b);
    printf("*: %lld/%lld\n",muldiv(a,b).a,muldiv(a,b).b);
    printf("/: %lld/%lld\n",divdiv(a,b).a,divdiv(a,b).b);
    printf("cmp: %d\n",cmpdiv(a,b));
    printf("value: %lf %lf\n",valueofdiv(a),valueofdiv(b));
}

GCD LCM 最大公約數 最小公倍數 分數模板 (防溢出優化完成)