/* GSoC12: Tobenna Peter, Igwe (Edited) */ Rat ratreduce (Rat a) { if (zero(a.num)) { /*a.den = 1;*/ itomp(1, a.den); } else { mp div; mp c; if (negative(a.den)) { /*a.den = -a.den;*/ changesign(a.den); /*a.num = -a.num;*/ changesign(a.num); } /*div = ratgcd(a.den, a.num);*/ ratgcd(a.den, a.num, div); /*a.num = a.num/div;*/ divint(a.num, div, c); copy(a.num, c); /*a.den = a.den/div;*/ divint(a.den, div, c); copy(a.den, c); } return a; }
void gcd ( lrs_mp u, lrs_mp v ) /*returns u=gcd(u,v) destroying v */ /*Euclid's algorithm. Knuth, II, p.320 modified to avoid copies r=u,u=v,v=r Switches to single precision when possible for greater speed */ { lrs_mp r; unsigned long ul, vl; long i; static unsigned long maxspval = MAXD; /* Max value for the last digit to guarantee */ /* fitting into a single long integer. */ static long maxsplen; /* Maximum digits for a number that will fit */ /* into a single long integer. */ static long firstime = TRUE; if ( firstime ) { /* initialize constants */ for ( maxsplen = 2; maxspval >= BASE; maxsplen++ ) maxspval /= BASE; firstime = FALSE; } if ( greater ( v, u ) ) goto bigv; bigu: if ( zero ( v ) ) return; if ( ( i = length ( u ) ) < maxsplen || ( i == maxsplen && u[maxsplen - 1] < maxspval ) ) goto quickfinish; divint ( u, v, r ); normalize ( u ); bigv: if ( zero ( u ) ) { copy ( u, v ); return; } if ( ( i = length ( v ) ) < maxsplen || ( i == maxsplen && v[maxsplen - 1] < maxspval ) ) goto quickfinish; divint ( v, u, r ); normalize ( v ); goto bigu; /* Base 10000 only at the moment */ /* when u and v are small enough, transfer to single precision integers */ /* and finish with euclid's algorithm, then transfer back to lrs_mp */ quickfinish: ul = vl = 0; for ( i = length ( u ) - 1; i > 0; i-- ) ul = BASE * ul + u[i]; for ( i = length ( v ) - 1; i > 0; i-- ) vl = BASE * vl + v[i]; if ( ul > vl ) goto qv; qu: if ( !vl ) { for ( i = 1; ul; i++ ) { u[i] = ul % BASE; ul = ul / BASE; } storelength ( u, i ); return; } ul %= vl; qv: if ( !ul ) { for ( i = 1; vl; i++ ) { u[i] = vl % BASE; vl = vl / BASE; } storelength ( u, i ); return; } vl %= ul; goto qu; }