bridge/class-master/depend/pari/src/basemath/gen1.c
/* True shift (exact multiplication by 2^n) */
True shift (exact multiplication by 2^n)
True shift ( exact multiplication by 2^n )
GEN
gmul2n(GEN x, long n)
{
  long lx, i, k, l;
  GEN z, a, b;
  switch(typ(x))
  {
    case t_INT:
      if (n>=0) return shifti(x,n);
      if (!signe(x)) return gen_0;
      l = vali(x); n = -n;
      if (n<=l) return shifti(x,-n);
      z = cgetg(3,t_FRAC);
      gel(z,1) = shifti(x,-l);
      gel(z,2) = int2n(n-l); return z;
    case t_REAL:
      return shiftr(x,n);
    case t_INTMOD: b = gel(x,1); a = gel(x,2);
      z = cgetg(3,t_INTMOD);
      if (n <= 0) return div_intmod_same(z, b, a, modii(int2n(-n), b));
      gel(z,2) = gerepileuptoint((pari_sp)z, modii(shifti(a,n), b));
      gel(z,1) = icopy(b); return z;
    case t_FFELT: return FF_mul2n(x,n);
    case t_FRAC: a = gel(x,1); b = gel(x,2);
      l = vali(a);
      k = vali(b);
      if (n+l >= k)
      {
        if (expi(b) == k) return shifti(a,n-k); 
        l = n-k; k = -k;
      }
      else
      {
        k = -(l+n); l = -l;
      }
      z = cgetg(3,t_FRAC);
      gel(z,1) = shifti(a,l);
      gel(z,2) = shifti(b,k); return z;
    case t_COMPLEX: z = cgetg(3,t_COMPLEX);
      gel(z,1) = gmul2n(gel(x,1),n);
      gel(z,2) = gmul2n(gel(x,2),n); return z;
    case t_QUAD: z = cgetg(4,t_QUAD);
      gel(z,1) = ZX_copy(gel(x,1));
      gel(z,2) = gmul2n(gel(x,2),n);
      gel(z,3) = gmul2n(gel(x,3),n); return z;
    case t_POLMOD:
      retmkpolmod(gmul2n(gel(x,2),n), RgX_copy(gel(x,1)));
    case t_POL:
      z = cgetg_copy(x, &lx); z[1] = x[1];
      for (i=2; i<lx; i++) gel(z,i) = gmul2n(gel(x,i),n);
      return normalizepol_lg(z, lx); 
    case t_SER:
      if (ser_isexactzero(x)) return gcopy(x);
      z = cgetg_copy(x, &lx); z[1] = x[1];
      for (i=2; i<lx; i++) gel(z,i) = gmul2n(gel(x,i),n);
      return normalize(z); 
    case t_VEC: case t_COL: case t_MAT:
      z = cgetg_copy(x, &lx);
      for (i=1; i<lx; i++) gel(z,i) = gmul2n(gel(x,i),n);
      return z;
    case t_RFRAC: 
      return mul_rfrac_scal(gel(x,1),gel(x,2), gmul2n(gen_1,n));
    case t_PADIC: 
      return gmul(gmul2n(gen_1,n),x);
  }
  pari_err_TYPE("gmul2n",x);
  return NULL; 
}
GEN gmul2n ( GEN x , long n ) { long lx , i , k , l ; GEN z , a , b ; switch ( typ ( x ) ) { case t_INT : if ( n >= 0 ) return shifti ( x , n ) ; if ( ! signe ( x ) ) return gen_0 ; l = vali ( x ) ; n = - n ; if ( n <= l ) return shifti ( x , - n ) ; z = cgetg ( 3 , t_FRAC ) ; gel ( z , 1 ) = shifti ( x , - l ) ; gel ( z , 2 ) = int2n ( n - l ) ; return z ; case t_REAL : return shiftr ( x , n ) ; case t_INTMOD : b = gel ( x , 1 ) ; a = gel ( x , 2 ) ; z = cgetg ( 3 , t_INTMOD ) ; if ( n <= 0 ) return div_intmod_same ( z , b , a , modii ( int2n ( - n ) , b ) ) ; gel ( z , 2 ) = gerepileuptoint ( ( pari_sp ) z , modii ( shifti ( a , n ) , b ) ) ; gel ( z , 1 ) = icopy ( b ) ; return z ; case t_FFELT : return FF_mul2n ( x , n ) ; case t_FRAC : a = gel ( x , 1 ) ; b = gel ( x , 2 ) ; l = vali ( a ) ; k = vali ( b ) ; if ( n + l >= k ) { if ( expi ( b ) == k ) return shifti ( a , n - k ) ; l = n - k ; k = - k ; } else { k = - ( l + n ) ; l = - l ; } z = cgetg ( 3 , t_FRAC ) ; gel ( z , 1 ) = shifti ( a , l ) ; gel ( z , 2 ) = shifti ( b , k ) ; return z ; case t_COMPLEX : z = cgetg ( 3 , t_COMPLEX ) ; gel ( z , 1 ) = gmul2n ( gel ( x , 1 ) , n ) ; gel ( z , 2 ) = gmul2n ( gel ( x , 2 ) , n ) ; return z ; case t_QUAD : z = cgetg ( 4 , t_QUAD ) ; gel ( z , 1 ) = ZX_copy ( gel ( x , 1 ) ) ; gel ( z , 2 ) = gmul2n ( gel ( x , 2 ) , n ) ; gel ( z , 3 ) = gmul2n ( gel ( x , 3 ) , n ) ; return z ; case t_POLMOD : retmkpolmod ( gmul2n ( gel ( x , 2 ) , n ) , RgX_copy ( gel ( x , 1 ) ) ) ; case t_POL : z = cgetg_copy ( x , & lx ) ; z [ 1 ] = x [ 1 ] ; for ( i = 2 ; i < lx ; i ++ ) gel ( z , i ) = gmul2n ( gel ( x , i ) , n ) ; return normalizepol_lg ( z , lx ) ; case t_SER : if ( ser_isexactzero ( x ) ) return gcopy ( x ) ; z = cgetg_copy ( x , & lx ) ; z [ 1 ] = x [ 1 ] ; for ( i = 2 ; i < lx ; i ++ ) gel ( z , i ) = gmul2n ( gel ( x , i ) , n ) ; return normalize ( z ) ; case t_VEC : case t_COL : case t_MAT : z = cgetg_copy ( x , & lx ) ; for ( i = 1 ; i < lx ; i ++ ) gel ( z , i ) = gmul2n ( gel ( x , i ) , n ) ; return z ; case t_RFRAC : return mul_rfrac_scal ( gel ( x , 1 ) , gel ( x , 2 ) , gmul2n ( gen_1 , n ) ) ; case t_PADIC : return gmul ( gmul2n ( gen_1 , n ) , x ) ; } pari_err_TYPE ( " " , x ) ; return NULL ; }
True shift (exact multiplication by 2^n)
True shift ( exact multiplication by 2^n )
/* b power of 2 */ /* needed if char = 2 */ /* needed if char = 2 */ /* int2n wrong if n < 0 */ /* int2n wrong if n < 0 */ /* LCOV_EXCL_LINE */