⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c_lip.c

📁 密码大家Shoup写的数论算法c语言实现
💻 C
📖 第 1 页 / 共 5 页
字号:
   } \   else if (lr21 >= denom) { \      lr21 -= denom; \      lq21++; \   } \   quot = lq21; \   numhigh = lr21; \}#if 0#define zdiv21(numhigh, numlow, denom, deninv, quot) \{ \   long lr21; \   long lq21 = (long) (((NTL_FRADIX * (double) (numhigh)) \          + (double) (numlow)) * (deninv)); \   long lp21; \   MulLo(lp21, lq21, denom); \   lr21 = (numhigh << NTL_NBITS) + numlow - lp21; \   if (lr21 < 0) \   { \      do \      { \         lq21--; \      } while ((lr21 += denom) < 0); \   } \   else \   { \      while (lr21 >= denom) \      { \         lr21 -= denom; \         lq21++; \      }; \   } \   quot = lq21; \   numhigh = lr21; \}#endif#if (NTL_ARITH_RIGHT_SHIFT && defined(NTL_AVOID_BRANCHING))#define zrem21(numhigh, numlow, denom, deninv) \{ \   long lr21; \   long lq21 = (long) (((NTL_FRADIX * (double) (numhigh)) \          + (double) (numlow)) * (deninv)); \   long lp21; \   MulLo(lp21, lq21, denom); \   lr21 = (numhigh << NTL_NBITS) + numlow - lp21; \   lr21 += (lr21 >> (NTL_BITS_PER_LONG-1)) & denom; \   lr21 -= denom; \   lr21 += (lr21 >> (NTL_BITS_PER_LONG-1)) & denom; \   numhigh = lr21; \}#else#define zrem21(numhigh, numlow, denom, deninv) \{ \   long lr21; \   long lq21 = (long) (((NTL_FRADIX * (double) (numhigh)) \      + (double) (numlow)) * (deninv)); \   long lp21; \   MulLo(lp21, lq21, denom); \   lr21 = (numhigh << NTL_NBITS) + numlow - lp21; \   if (lr21 < 0) lr21 += denom; \   else if (lr21 >= denom) lr21 -= denom; \   numhigh = lr21; \}#endifvoid _ntl_zsetlength(_ntl_verylong *v, long len){   _ntl_verylong x = *v;   if (len < 0)      zhalt("negative size allocation in _ntl_zsetlength");   if (len >= (1L << (NTL_BITS_PER_LONG-4))/NTL_NBITS)      zhalt("size too big in _ntl_zsetlength");#ifdef L_TO_G_CHECK_LEN   /* this makes sure that numbers don't get too big for GMP */   if (len >= (1L << (NTL_BITS_PER_INT-4)))      zhalt("size too big for GMP");#endif   if (x) {      long oldlen = x[-1];      long fixed = oldlen & 1;      oldlen = oldlen >> 1;      if (fixed) {         if (len > oldlen)             zhalt("internal error: can't grow this _ntl_verylong");         else            return;      }      if (len <= oldlen) return;      len++;  /* always allocate at least one more than requested */      oldlen = (long) (oldlen * 1.2); /* always increase by at least 20% */      if (len < oldlen)         len = oldlen;      /* round up to multiple of MIN_SETL */      len = ((len+(MIN_SETL-1))/MIN_SETL)*MIN_SETL;       /* test len again */      if (len >= (1L << (NTL_BITS_PER_LONG-4))/NTL_NBITS)         zhalt("size too big in _ntl_zsetlength");      x[-1] = len << 1;      if (!(x = (_ntl_verylong)realloc((void*)(&(x[-1])), (len + 2) * (sizeof (long))))) {         zhalt("reallocation failed in _ntl_zsetlength");      }   }   else {      len++;      len = ((len+(MIN_SETL-1))/MIN_SETL)*MIN_SETL;      /* test len again */      if (len >= (1L << (NTL_BITS_PER_LONG-4))/NTL_NBITS)         zhalt("size too big in _ntl_zsetlength");      if (!(x = (_ntl_verylong)malloc((len + 2)*(sizeof (long))))) {         zhalt("allocation failed in _ntl_zsetlength");      }      x[0] = len << 1;      x[1] = 1;      x[2] = 0;   }   *v = x+1;}void _ntl_zfree(_ntl_verylong *x){   _ntl_verylong y;   if (!(*x))      return;   if ((*x)[-1] & 1)      zhalt("Internal error: can't free this _ntl_verylong");   y = (*x - 1);   free((void*)y);   *x = 0;}long _ntl_zround_correction(_ntl_verylong a, long k, long residual){   long direction;   long p;   long sgn;   long bl;   long wh;   long i;   if (a[0] > 0)      sgn = 1;   else      sgn = -1;   p = k - 1;   bl = (p/NTL_NBITS);   wh = 1L << (p - NTL_NBITS*bl);   bl++;   if (a[bl] & wh) {      /* bit is 1...we have to see if lower bits are all 0         in order to implement "round to even" */      if (a[bl] & (wh - 1))          direction = 1;      else {         i = bl - 1;         while (i > 0 && a[i] == 0) i--;         if (i > 0)            direction = 1;         else            direction = 0;      }      /* use residual to break ties */      if (direction == 0 && residual != 0) {         if (residual == sgn)            direction = 1;         else             direction = -1;      }      if (direction == 0) {         /* round to even */         wh = wh << 1;         if (wh == NTL_RADIX) {            wh = 1;            bl++;         }         if (a[bl] & wh)            direction = 1;         else            direction = -1;      }   }   else      direction = -1;   if (direction == 1)      return sgn;   return 0;}double _ntl_zdoub_aux(_ntl_verylong n){   double res;   long i;   if (!n)      return ((double) 0);   if ((i = n[0]) < 0)      i = -i;   res = (double) (n[i--]);   for (; i; i--)      res = res * NTL_FRADIX + (double) (n[i]);   if (n[0] > 0)      return (res);   return (-res);}double _ntl_zdoub(_ntl_verylong n){   static _ntl_verylong tmp = 0;   long s;   long shamt;   long correction;   double x;   s = _ntl_z2log(n);   shamt = s - NTL_DOUBLE_PRECISION;   if (shamt <= 0)      return _ntl_zdoub_aux(n);   _ntl_zrshift(n, shamt, &tmp);   correction = _ntl_zround_correction(n, shamt, 0);   if (correction) _ntl_zsadd(tmp, correction, &tmp);   x = _ntl_zdoub_aux(tmp);   /* We could just write x = ldexp(x, shamt); however, if long's    * are bigger than int's, there is the possibility that shamt would be    * truncated.  We could check for this and raise an error, but    * it is preferable to do it this way to get +/- infinity, if    * possible. */   while (shamt > 1024) {      x = ldexp(x, 1024);      shamt -= 1024;   }   x = ldexp(x, shamt);   return x;}double _ntl_zlog(_ntl_verylong n){   static _ntl_verylong tmp = 0;   static double log_2;   static long init = 0;   long s;   long shamt;   long correction;   double x;   if (!init) {      log_2 = log(2.0);      init = 1;   }   if (_ntl_zsign(n) <= 0)      zhalt("log argument <= 0");   s = _ntl_z2log(n);   shamt = s - NTL_DOUBLE_PRECISION;   if (shamt <= 0)      return log(_ntl_zdoub_aux(n));   _ntl_zrshift(n, shamt, &tmp);   correction = _ntl_zround_correction(n, shamt, 0);   if (correction) _ntl_zsadd(tmp, correction, &tmp);   x = _ntl_zdoub_aux(tmp);   return log(x) + shamt*log_2;}void _ntl_zdoubtoz(double a, _ntl_verylong *xx){   _ntl_verylong x;   long neg, i, t, sz;   a = floor(a);   if (!_ntl_IsFinite(&a))      zhalt("_ntl_zdoubtoz: attempt to convert non-finite value");   if (a < 0) {      a = -a;      neg = 1;   }   else      neg = 0;   if (a == 0) {      _ntl_zzero(xx);      return;   }   sz = 1;   a = a*NTL_FRADIX_INV;   while (a >= 1) {      a = a*NTL_FRADIX_INV;      sz++;   }            x = *xx;   if (MustAlloc(x, sz)) {      _ntl_zsetlength(&x, sz);      *xx = x;   }   for (i = sz; i > 0; i--) {      a = a*NTL_FRADIX;      t = (long) a;      x[i] = t;      a = a - t;   }   x[0] = (neg ? -sz : sz);}void _ntl_zzero(_ntl_verylong *aa){   if (!(*aa)) _ntl_zsetlength(aa, 1);   (*aa)[0] =  1;   (*aa)[1] =  0;}/* same as _ntl_zzero, except does not unnecessarily allocate space */void _ntl_zzero1(_ntl_verylong *aa){   if (!(*aa)) return;   (*aa)[0] =  1;   (*aa)[1] =  0;}void _ntl_zone(_ntl_verylong *aa){   if (!(*aa)) _ntl_zsetlength(aa, 1);   (*aa)[0] =  1;   (*aa)[1] =  1;}void _ntl_zcopy(_ntl_verylong a, _ntl_verylong *bb){   long i;   _ntl_verylong b = *bb;   if (!a) {      _ntl_zzero(bb);      return;   }   if (a != b) {      if ((i = *a) < 0)         i = (-i);      if (MustAlloc(b, i)) {         _ntl_zsetlength(&b, i);         *bb = b;      }      for (; i >= 0; i--)         *b++ = *a++;   }}/* same as _ntl_zcopy, but does not unnecessarily allocate space */void _ntl_zcopy1(_ntl_verylong a, _ntl_verylong *bb){   long i;   _ntl_verylong b = *bb;   if (!a) {      _ntl_zzero1(bb);      return;   }   if (a != b) {      if ((i = *a) < 0)         i = (-i);      if (MustAlloc(b, i)) {         _ntl_zsetlength(&b, i);         *bb = b;      }      for (; i >= 0; i--)         *b++ = *a++;   }}void _ntl_zintoz(long d, _ntl_verylong *aa){   long i;   long anegative;   unsigned long d1, d2;   _ntl_verylong a = *aa;   anegative = 0;   if (d < 0) {      anegative = 1;      d1 = - ((unsigned long) d);   }   else      d1 = d;   i = 0;   d2 = d1;   do {      d2 >>= NTL_NBITS;      i++;   }   while (d2 > 0);   if (MustAlloc(a, i)) {      _ntl_zsetlength(&a, i);      *aa = a;   }   i = 0;   a[1] = 0;   while (d1 > 0) {      a[++i] = d1 & NTL_RADIXM;      d1 >>= NTL_NBITS;   }   if (i > 0)      a[0] = i;   else      a[0] = 1;   if (anegative)      a[0] = (-a[0]);}/* same as _ntl_zintoz, but does not unnecessarily allocate space */void _ntl_zintoz1(long d, _ntl_verylong *aa){   long i;   long anegative;   unsigned long d1, d2;   _ntl_verylong a = *aa;   if (!d && !a) return;   anegative = 0;   if (d < 0) {      anegative = 1;      d1 = -d;   }   else      d1 = d;   i = 0;   d2 = d1;   do {      d2 >>= NTL_NBITS;      i++;   }   while (d2 > 0);   if (MustAlloc(a, i)) {      _ntl_zsetlength(&a, i);      *aa = a;   }   i = 0;   a[1] = 0;   while (d1 > 0) {      a[++i] = d1 & NTL_RADIXM;      d1 >>= NTL_NBITS;   }   if (i > 0)      a[0] = i;   else      a[0] = 1;   if (anegative)      a[0] = (-a[0]);}void _ntl_zuintoz(unsigned long d, _ntl_verylong *aa){   long i;   unsigned long d1, d2;   _ntl_verylong a = *aa;   d1 = d;   i = 0;   d2 = d1;   do {      d2 >>= NTL_NBITS;      i++;   }   while (d2 > 0);   if (MustAlloc(a, i)) {      _ntl_zsetlength(&a, i);      *aa = a;   }   i = 0;   a[1] = 0;   while (d1 > 0) {      a[++i] = d1 & NTL_RADIXM;      d1 >>= NTL_NBITS;   }   if (i > 0)      a[0] = i;   else      a[0] = 1;}long _ntl_ztoint(_ntl_verylong a){   long d;   long sa;   if (!a)      return (0);   if ((sa = *a) < 0)      sa = -sa;   d = *(a += sa);   while (--sa) {      d <<= NTL_NBITS;      d += *(--a);   }   if ((*(--a)) < 0)      return (-d);   return (d);}unsigned long _ntl_ztouint(_ntl_verylong a){   unsigned long d;   long sa;   if (!a)      return (0);   if ((sa = *a) < 0)      sa = -sa;   d = (unsigned long) (*(a += sa));   while (--sa) {      d <<= NTL_NBITS;      d += (unsigned long) (*(--a));   }   if ((*(--a)) < 0)      return (-d);   return (d);}long _ntl_zcompare(_ntl_verylong a, _ntl_verylong b){   long sa;   long sb;   if (!a) {      if (!b)         return (0);      if (b[0] < 0)         return (1);      if (b[0] > 1)         return (-1);      if (b[1])         return (-1);      return (0);   }   if (!b) {      if (a[0] < 0)         return (-1);      if (a[0] > 1)         return (1);      if (a[1])         return (1);      return (0);   }   if ((sa = *a) > (sb = *b))      return (1);   if (sa < sb)      return (-1);   if (sa < 0)      sa = (-sa);   a += sa;   b += sa;   for (; sa; sa--) {      if (*a > *b) {         if (sb < 0)            return (-1);         return (1);      }      if (*a-- < *b--) {         if (sb < 0)            return (1);         return (-1);      }   }   return (0);}void _ntl_znegate(_ntl_verylong *aa){   _ntl_verylong a = *aa;   if (!a)      return;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -