自己写的一个分数模板,在运算操作时进行了防溢出的优化:
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 ",plusdiv(a,b).a,plusdiv(a,b).b); printf("-: %lld/%lld ",minusdiv(a,b).a,minusdiv(a,b).b); printf("*: %lld/%lld ",muldiv(a,b).a,muldiv(a,b).b); printf("/: %lld/%lld ",divdiv(a,b).a,divdiv(a,b).b); printf("cmp: %d ",cmpdiv(a,b)); printf("value: %lf %lf ",valueofdiv(a),valueofdiv(b)); }