?? c_lip_impl.h
字號:
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 (NTL_OVERFLOW(len, NTL_NBITS, 0))
zhalt("size too big in _ntl_zsetlength");
x[-1] = len << 1;
if (!(x = (_ntl_verylong)NTL_REALLOC(&(x[-1]),
len, sizeof(long), 2*sizeof(long)))) {
zhalt("reallocation failed in _ntl_zsetlength");
}
}
else {
len++;
len = ((len+(MIN_SETL-1))/MIN_SETL)*MIN_SETL;
/* test len again */
if (NTL_OVERFLOW(len, NTL_NBITS, 0))
zhalt("size too big in _ntl_zsetlength");
if (!(x = (_ntl_verylong)NTL_MALLOC(len,
sizeof(long), 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);
x = _ntl_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); /* careful: avoid overflow */
}
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 = - ((unsigned long) d); /* careful: avoid overlow */
}
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;
}
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_ztoint(_ntl_verylong a)
{
unsigned long res = _ntl_ztouint(a);
return NTL_ULONG_TO_LONG(res);
}
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--) {
long diff = *a - *b;
if (diff > 0) {
if (sb < 0)
return (-1);
return (1);
}
if (diff < 0) {
if (sb < 0)
return (1);
return (-1);
}
a--;
b--;
}
return (0);
}
void _ntl_znegate(_ntl_verylong *aa)
{
_ntl_verylong a = *aa;
if (!a)
return;
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;
_ntl_verylong c;
long a_alias, b_alias;
if (!a) {
if (b)
_ntl_zcopy(b, cc);
else
_ntl_zzero(cc);
return;
}
if (!b) {
_ntl_zcopy(a, cc);
return;
}
c = *cc;
a_alias = (a == c);
b_alias = (b == c);
if ((anegative = ((sa = a[0]) < 0)) == ((sb = b[0]) < 0)) {
/* signs a and b are the same */
_ntl_verylong pc;
long carry;
long i;
long maxab;
if (anegative) {
sa = -sa;
sb = -sb;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -