bridge/class-master/depend/pari/src/kernel/none/gcd.c
/* uses modified right-shift binary algorithm now --GN 1998Jul23 */
uses modified right-shift binary algorithm now --GN 1998Jul23
uses modified right - shift binary algorithm now -- GN 1998Jul23
GEN
gcdii(GEN a, GEN b)
{
  long v, w;
  pari_sp av;
  GEN t, p1;
  switch (abscmpii(a,b))
  {
    case 0: return absi(a);
    case -1: swap(a,b);
  }
  if (!signe(b)) return absi(a);
  if (lgefint(a)==3)
    return igcduu((ulong)a[2], (ulong)b[2]);
  if (lgefint(b)==3)
  {
    ulong u = resiu(a,(ulong)b[2]);
    if (!u) return absi(b);
    return igcduu((ulong)b[2], u);
  }
  av = avma; (void)new_chunk(lgefint(b)); 
  t = remii(a,b);
  if (!signe(t)) { avma = av; return absi(b); }
  a = b; b = t;
  v = vali(a); a = shifti(a,-v); setabssign(a);
  w = vali(b); b = shifti(b,-w); setabssign(b);
  if (w < v) v = w;
  switch(abscmpii(a,b))
  {
    case  0: avma = av; a = shifti(a,v); return a;
    case -1: swap(a,b);
  }
  if (is_pm1(b)) { avma = av; return int2n(v); }
  while (lgefint(a) > 3)
  {
    gcd_plus_minus(a,b, t);
    if (is_pm1(t)) { avma = av; return int2n(v); }
    switch(abscmpii(t,b))
    {
      case -1: p1 = a; a = b; b = t; t = p1; break;
      case  1: swap(a,t); break;
      case  0: avma = av; b = shifti(b,v); return b;
    }
  }
  {
    long r[] = {evaltyp(t_INT)|_evallg(3), evalsigne(1)|evallgefint(3), 0};
    r[2] = (long) gcduodd((ulong)b[2], (ulong)a[2]);
    avma = av; return shifti(r,v);
  }
}
GEN gcdii ( GEN a , GEN b ) { long v , w ; pari_sp av ; GEN t , p1 ; switch ( abscmpii ( a , b ) ) { case 0 : return absi ( a ) ; case -1 : swap ( a , b ) ; } if ( ! signe ( b ) ) return absi ( a ) ; if ( lgefint ( a ) == 3 ) return igcduu ( ( ulong ) a [ 2 ] , ( ulong ) b [ 2 ] ) ; if ( lgefint ( b ) == 3 ) { ulong u = resiu ( a , ( ulong ) b [ 2 ] ) ; if ( ! u ) return absi ( b ) ; return igcduu ( ( ulong ) b [ 2 ] , u ) ; } av = avma ; ( void ) new_chunk ( lgefint ( b ) ) ; t = remii ( a , b ) ; if ( ! signe ( t ) ) { avma = av ; return absi ( b ) ; } a = b ; b = t ; v = vali ( a ) ; a = shifti ( a , - v ) ; setabssign ( a ) ; w = vali ( b ) ; b = shifti ( b , - w ) ; setabssign ( b ) ; if ( w < v ) v = w ; switch ( abscmpii ( a , b ) ) { case 0 : avma = av ; a = shifti ( a , v ) ; return a ; case -1 : swap ( a , b ) ; } if ( is_pm1 ( b ) ) { avma = av ; return int2n ( v ) ; } while ( lgefint ( a ) > 3 ) { gcd_plus_minus ( a , b , t ) ; if ( is_pm1 ( t ) ) { avma = av ; return int2n ( v ) ; } switch ( abscmpii ( t , b ) ) { case -1 : p1 = a ; a = b ; b = t ; t = p1 ; break ; case 1 : swap ( a , t ) ; break ; case 0 : avma = av ; b = shifti ( b , v ) ; return b ; } } { long r [ ] = { evaltyp ( t_INT ) | _evallg ( 3 ) , evalsigne ( 1 ) | evallgefint ( 3 ) , 0 } ; r [ 2 ] = ( long ) gcduodd ( ( ulong ) b [ 2 ] , ( ulong ) a [ 2 ] ) ; avma = av ; return shifti ( r , v ) ; } }
uses modified right-shift binary algorithm now --GN 1998Jul23
uses modified right - shift binary algorithm now -- GN 1998Jul23
/* here |a|>|b|>0. Try single precision first */ /* larger than gcd: "avma=av" gerepile (erasing t) is valid */ /* HACK */ /* we have three consecutive memory locations: a,b,t.
   * All computations are done in place */ /* a and b are odd now, and a>b>1 */ /* if a=b mod 4 set t=a-b, otherwise t=a+b, then strip powers of 2 */ /* so that t <= (a+b)/4 < a/2 */