📄 c_lip.c
字号:
if (a[1] || a[0] != 1) a[0] = (-a[0]);}void _ntl_zsadd(_ntl_verylong a, long d, _ntl_verylong *b){ static _ntl_verylong x = 0; _ntl_zintoz(d, &x); _ntl_zadd(a, x, b);}void_ntl_zadd(_ntl_verylong a, _ntl_verylong b, _ntl_verylong *cc){ long sa; long sb; long anegative; if (!a) { if (b) _ntl_zcopy(b, cc); else _ntl_zzero(cc); return; } if (!b) { _ntl_zcopy(a, cc); return; } if ((anegative = ((sa = a[0]) < 0)) == ((sb = b[0]) < 0)) { /* signs a and b are the same */ _ntl_verylong pc, c; long carry; long i; long maxab; if (anegative) { sa = -sa; sb = -sb; } if (sa < sb) { i = sa; maxab = sb; } else { i = sb; maxab = sa; } c = *cc; if (MustAlloc(c, maxab+1)) { _ntl_verylong c1 = c; _ntl_zsetlength(&c1, maxab + 1); if (a == c) a = c1; if (b == c) b = c1; *cc = c = c1; } pc = c; carry = 0; do { long t = (*(++a)) + (*(++b)) + carry; carry = t >> NTL_NBITS; *(++pc) = t & NTL_RADIXM; i--; } while (i); i = sa-sb; if (!i) goto i_exit; if (i < 0) { i = -i; a = b; } if (!carry) goto carry_exit; for (;;) { long t = (*(++a)) + 1; carry = t >> NTL_NBITS; *(++pc) = t & NTL_RADIXM; i--; if (!i) goto i_exit; if (!carry) goto carry_exit; } i_exit: if (carry) { *(++pc) = 1; maxab++; } *c = anegative ? -maxab : maxab; return; carry_exit: if (pc != a) { do { *(++pc) = *(++a); i--; } while (i); } *c = anegative ? -maxab : maxab; } else { /* signs a and b are different...use _ntl_zsub */ _ntl_verylong c = *cc; if (anegative) { a[0] = -sa; _ntl_zsub(b, a, cc); if (a != c) a[0] = sa; } else { b[0] = -sb; _ntl_zsub(a, b, cc); if (b != c) b[0] = sb; } }}void_ntl_zsub(_ntl_verylong a, _ntl_verylong b, _ntl_verylong *cc){ long sa; long sb; long anegative; if (!b) { if (a) _ntl_zcopy(a, cc); else _ntl_zzero(cc); return; } if (!a) { _ntl_zcopy(b, cc); _ntl_znegate(cc); return; } if ((anegative = ((sa = a[0]) < 0)) == ((sb = b[0]) < 0)) { /* signs agree */ long i, carry, *pc, *c; if (anegative) { sa = -sa; sb = -sb; } carry = sa - sb; if (!carry) { long *aa = a + sa; long *bb = b + sa; i = sa; while (i && !(carry = (*aa - *bb))) { aa--; bb--; i--; } } if (!carry) { _ntl_zzero(cc); return; } if (carry < 0) { { long t = sa; sa = sb; sb = t; } { long *t = a; a = b; b = t; } anegative = !anegative; } c = *cc; if (MustAlloc(c, sa)) { _ntl_verylong c1 = c; _ntl_zsetlength(&c1, sa); if (b == c) b = c1; *cc = c = c1; } i = sb; carry = 0; pc = c; do {#if (!NTL_ARITH_RIGHT_SHIFT) long t = (*(++a)) - (*(++b)) - carry; carry = (t < 0);#else long t = (*(++a)) - (*(++b)) + carry; carry = t >> NTL_NBITS;#endif *(++pc) = t & NTL_RADIXM; i--; } while (i); i = sa-sb; while (carry) { long t = (*(++a)) - 1;#if (!NTL_ARITH_RIGHT_SHIFT) carry = (t < 0);#else carry = t >> NTL_NBITS;#endif *(++pc) = t & NTL_RADIXM; i--; } if (i) { if (pc != a) { do { *(++pc) = *(++a); i--; } while (i); } } else { while (sa > 1 && *pc == 0) { sa--; pc--; } } if (anegative) sa = -sa; *c = sa; } else { /* signs of a and b are different...use _ntl_zadd */ _ntl_verylong c = *cc; if (anegative) { a[0] = -sa; _ntl_zadd(a, b, cc); if (a != c) a[0] = sa; c = *cc; c[0] = -c[0]; } else { b[0] = -sb; _ntl_zadd(a, b, cc); if (b != c) b[0] = sb; } }}void_ntl_zsmul(_ntl_verylong a, long d, _ntl_verylong *bb){ long sa; long anegative, bnegative; _ntl_verylong b; if (d == 2) { _ntl_z2mul(a, bb); return; } if ((d >= NTL_RADIX) || (d <= -NTL_RADIX)) { static _ntl_verylong x = 0; _ntl_zintoz(d,&x); _ntl_zmul(a, x, bb); return; } if (!a) { _ntl_zzero(bb); return; } if (!d) { _ntl_zzero(bb); return; } anegative = 0; bnegative = 0; if ((sa = a[0]) < 0) { anegative = 1; a[0] = sa = (-sa); if (d < 0) d = (-d); else bnegative = 1; } else if (bnegative = (d < 0)) d = (-d); b = *bb; if (MustAlloc(b, sa + 1)) { _ntl_zsetlength(&b, sa + 1); if (a == *bb) a = b; *bb = b; } zsxmul(d, b+1, a); sa++; while ((sa > 1) && (!(b[sa]))) sa--; b[0] = sa; if (bnegative && (b[1] || b[0] != 1)) b[0] = (-b[0]); if (anegative && a != b) a[0] = -a[0];}void _ntl_zsubpos(_ntl_verylong a, _ntl_verylong b, _ntl_verylong *cc){ long sa; long sb; long *c, *pc; long i, carry; if (!b) { if (a) _ntl_zcopy(a, cc); else _ntl_zzero(cc); return; } if (!a) { _ntl_zzero(cc); return; } sa = a[0]; sb = b[0]; c = *cc; if (MustAlloc(c, sa)) { _ntl_verylong c1 = c; _ntl_zsetlength(&c1, sa); if (b == c) b = c1; *cc = c = c1; } i = sb; carry = 0; pc = c; while (i) {#if (!NTL_ARITH_RIGHT_SHIFT) long t = (*(++a)) - (*(++b)) - carry; carry = (t < 0);#else long t = (*(++a)) - (*(++b)) + carry; carry = t >> NTL_NBITS;#endif *(++pc) = t & NTL_RADIXM; i--; } i = sa-sb; while (carry) { long t = (*(++a)) - 1;#if (!NTL_ARITH_RIGHT_SHIFT) carry = (t < 0);#else carry = t >> NTL_NBITS;#endif *(++pc) = t & NTL_RADIXM; i--; } if (i) { if (pc != a) { do { *(++pc) = *(++a); i--; } while (i); } } else { while (sa > 1 && *pc == 0) { sa--; pc--; } } *c = sa;}static long *kmem = 0; /* globals for Karatsuba */static long max_kmem = 0;/* These cross-over points were estimated using a Sparc-10, a Sparc-20, and a Pentium-90. */#if (defined(NTL_SINGLE_MUL))#define KARX (18)#else#define KARX (16) #endif/* Auxilliary routines for Karatsuba */staticvoid kar_fold(long *T, long *b, long hsa){ long sb, *p2, *p3, i, carry; sb = *b; p2 = b + hsa; p3 = T; carry = 0; for (i = sb-hsa; i>0; i--) { long t = (*(++b)) + (*(++p2)) + carry; carry = t >> NTL_NBITS; *(++p3) = t & NTL_RADIXM; } for (i = (hsa << 1) - sb; i>0; i--) { long t = (*(++b)) + carry; carry = t >> NTL_NBITS; *(++p3) = t & NTL_RADIXM; } if (carry) { *(++p3) = carry; *T = hsa + 1; } else *T = hsa;}staticvoid kar_sub(long *T, long *c){ long i, carry; i = *c; carry = 0; while (i>0) {#if (!NTL_ARITH_RIGHT_SHIFT) long t = (*(++T)) - (*(++c)) - carry; carry = (t < 0);#else long t = (*(++T)) - (*(++c)) + carry; carry = t >> NTL_NBITS;#endif *T = t & NTL_RADIXM; i--; } while (carry) { long t = (*(++T)) - 1;#if (!NTL_ARITH_RIGHT_SHIFT) carry = (t < 0);#else carry = t >> NTL_NBITS;#endif *T = t & NTL_RADIXM; }}staticvoid kar_add(long *c, long *T, long hsa){ long i, carry; c += hsa; i = *T; while (T[i] == 0 && i > 0) i--; carry = 0; while (i>0) { long t = (*(++c)) + (*(++T)) + carry; carry = t >> NTL_NBITS; *c = t & NTL_RADIXM; i--; } while (carry) { long t = (*(++c)) + 1; carry = t >> NTL_NBITS; *c = t & NTL_RADIXM; }}staticvoid kar_fix(long *c, long *T, long hsa){ long i, carry, s; s = *T; i = hsa; while (i>0) { *(++c) = *(++T); i--; } i = s - hsa; carry = 0; while (i > 0) { long t = (*(++c)) + (*(++T)) + carry; carry = t >> NTL_NBITS; *c = t & NTL_RADIXM; i--; } while (carry) { long t = (*(++c)) + 1; carry = t >> NTL_NBITS; *c = t & NTL_RADIXM; }} staticvoid kar_mul(long *c, long *a, long *b, long *stk){ long sa, sb, sc; if (*a < *b) { long *t = a; a = b; b = t; } sa = *a; sb = *b; sc = sa + sb; if (sb < KARX) { /* classic algorithm */ long *pc, i, *pb; pc = c; for (i = sc; i; i--) { pc++; *pc = 0; } pc = c; pb = b; for (i = sb; i; i--) { pb++; pc++; zaddmul(*pb, pc, a); } } else { long hsa = (sa + 1) >> 1; if (hsa < sb) { /* normal case */ long *T1, *T2, *T3; /* allocate space */ T1 = stk; stk += hsa + 2; T2 = stk; stk += hsa + 2; T3 = stk; stk += (hsa << 1) + 3; if (stk-kmem > max_kmem) zhalt("internal error: kmem overflow"); /* compute T1 = a_lo + a_hi */ kar_fold(T1, a, hsa); /* compute T2 = b_lo + b_hi */ kar_fold(T2, b, hsa); /* recursively compute T3 = T1 * T2 */ kar_mul(T3, T1, T2, stk); /* recursively compute a_hi * b_hi into high part of c */ /* and subtract from T3 */ { long olda, oldb; olda = a[hsa]; a[hsa] = sa-hsa; oldb = b[hsa]; b[hsa] = sb-hsa; kar_mul(c + (hsa << 1), a + hsa, b + hsa, stk); kar_sub(T3, c + (hsa << 1)); a[hsa] = olda; b[hsa] = oldb; } /* recursively compute a_lo*b_lo into low part of c */ /* and subtract from T3 */ *a = hsa; *b = hsa; kar_mul(c, a, b, stk); kar_sub(T3, c); *a = sa; *b = sb; /* finally, add T3 * NTL_RADIX^{hsa} to c */ kar_add(c, T3, hsa); } else { /* degenerate case */ long *T; T = stk; stk += sb + hsa + 1; if (stk-kmem > max_kmem) zhalt("internal error: kmem overflow"); /* recursively compute b*a_hi into high part of c */ { long olda; olda = a[hsa]; a[hsa] = sa-hsa; kar_mul(c + hsa, a + hsa, b, stk); a[hsa] = olda; } /* recursively compute b*a_lo into T */ *a = hsa; kar_mul(T, a, b, stk); *a = sa; /* fix-up result */ kar_fix(c, T, hsa); } } /* normalize result */ while (c[sc] == 0 && sc > 1) sc--; *c = sc;}#if (defined(NTL_SINGLE_MUL))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -