📄 c_lip.c
字号:
} \ 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 + -