?? c_lip_impl.h
字號:
long lams = 0;
lams = 0;
for (lami = (*lamb++); lami > 0; lami--) {
lams += (*lama - *lamb++);
*lama++ = lams & NTL_RADIXM;
lams >>= NTL_NBITS;
}
*lama += lams;
}
#else
static
void zsubmulone(long *lama, long *lamb)
{
long lami;
long lams = 0;
lams = 0;
for (lami = (*lamb++); lami > 0; lami--) {
lams = *lama - *lamb++ - lams;
*lama++ = lams & NTL_RADIXM;
lams = (lams < 0);
}
*lama -= lams;
}
#endif
/*
* definitions of zaddmul, zsxmul, zaddmulsq for the various
* long integer implementation options.
*/
#if (defined(NTL_SINGLE_MUL))
static
void zaddmul(long ams, long *ama, long *amb)
{
long carry = 0;
long i = (*amb++);
double dams = (double) ams;
double xx;
double yy;
unsigned long lo_wd, lo;
unsigned long hi_wd, hi;
xx = ((double) (*amb++))*dams + DENORMALIZE;
for (; i > 1; i--) {
yy = ((double) (*amb++))*dams +DENORMALIZE;
NTL_FetchHiLo(hi_wd, lo_wd, xx);
lo = lo_wd & 0x3FFFFFF;
hi = ((hi_wd<<6)|(lo_wd>>26)) & 0x3FFFFFF;
lo = lo + (*ama) + carry;
*ama = lo & 0x3FFFFFF;
carry = hi + (lo >> 26);
ama++;
xx = yy;
}
NTL_FetchHiLo(hi_wd, lo_wd, xx);
lo = lo_wd & 0x3FFFFFF;
hi = ((hi_wd<<6)|(lo_wd>>26)) & 0x3FFFFFF;
lo = lo + (*ama) + carry;
*ama = lo & 0x3FFFFFF;
carry = hi + (lo >> 26);
ama++;
*ama += carry;
}
static
void zsxmul(long ams, long *ama, long *amb)
{
long carry = 0;
long i = (*amb++);
double dams = (double) ams;
double xx;
double yy;
unsigned long lo_wd, lo;
unsigned long hi_wd, hi;
xx = ((double) (*amb++))*dams + DENORMALIZE;
for (; i > 1; i--) {
yy = ((double) (*amb++))*dams +DENORMALIZE;
NTL_FetchHiLo(hi_wd, lo_wd, xx);
lo = lo_wd & 0x3FFFFFF;
hi = ((hi_wd<<6)|(lo_wd>>26)) & 0x3FFFFFF;
lo = lo + carry;
*ama = lo & 0x3FFFFFF;
carry = hi + (lo >> 26);
ama++;
xx = yy;
}
NTL_FetchHiLo(hi_wd, lo_wd, xx);
lo = lo_wd & 0x3FFFFFF;
hi = ((hi_wd<<6)|(lo_wd>>26)) & 0x3FFFFFF;
lo = lo + carry;
*ama = lo & 0x3FFFFFF;
carry = hi + (lo >> 26);
ama++;
*ama = carry;
}
static
void zaddmulsq(long ams, long *ama, long *amb)
{
long carry = 0;
long i = ams;
double dams = (double) (*amb++);
double xx;
double yy;
unsigned long lo, lo_wd;
unsigned long hi, hi_wd;
xx = ((double) (*amb++))*dams + DENORMALIZE;
for (; i > 1; i--) {
yy = ((double) (*amb++))*dams + DENORMALIZE;
NTL_FetchHiLo(hi_wd, lo_wd, xx);
lo = lo_wd & 0x3FFFFFF;
hi = ((hi_wd<<6)|(lo_wd>>26)) & 0x3FFFFFF;
lo = lo + (*ama) + carry;
*ama = lo & 0x3FFFFFF;
carry = hi + (lo >> 26);
ama++;
xx = yy;
}
if (i==1) {
NTL_FetchHiLo(hi_wd, lo_wd, xx);
lo = lo_wd & 0x3FFFFFF;
hi = ((hi_wd<<6)|(lo_wd>>26)) & 0x3FFFFFF;
lo = lo + (*ama) + carry;
*ama = lo & 0x3FFFFFF;
carry = hi + (lo >> 26);
ama++;
}
*ama += carry;
}
#elif (defined(NTL_AVOID_FLOAT) || defined(NTL_LONG_LONG))
static
void zaddmul(long lams, long *lama, long *lamb)
{
long lami;
long lamcarry = 0;
for (lami = (*lamb++); lami > 0; lami--)
{
zaddmulp(*lama, *lamb, lams, lamcarry);
lama++;
lamb++;
}
*lama += lamcarry;
}
static
void zsxmul(long lams, long *lama, long *lamb)
{
long lami;
long lamcarry = 0;
for (lami = (*lamb++); lami > 0; lami--)
{
zxmulp(*lama, *lamb, lams, lamcarry);
lama++;
lamb++;
}
*lama = lamcarry;
}
static
void zaddmulsq(long lsqi, long *lsqa, long *lsqb)
{
long lsqs = *(lsqb);
long lsqcarry = 0;
lsqb++;
for (; lsqi > 0; lsqi--)
{
zaddmulp(*lsqa, *lsqb, lsqs, lsqcarry);
lsqa++;
lsqb++;
}
*lsqa += lsqcarry;
}
#else
/* default long integer arithmetic */
static
void zaddmul(long lams, long *lama, long *lamb)
{
long lami = (*lamb++)-1;
long lamcarry = 0;
zam_decl;
zam_init(*lamb, lams);
lamb++;
for (; lami > 0; lami--) {
zam_loop(*lama, lamcarry, *lamb);
lama++;
lamb++;
}
zam_finish(*lama, lamcarry);
lama++;
*lama += lamcarry;
}
static
void zsxmul(long lams, long *lama, long *lamb)
{
long lami = (*lamb++)-1;
long lamcarry = 0;
zam_decl;
zam_init(*lamb, lams);
lamb++;
for (; lami > 0; lami--) {
zsx_loop(*lama, lamcarry, *lamb);
lama++;
lamb++;
}
zsx_finish(*lama, lamcarry);
lama++;
*lama = lamcarry;
}
static
void zaddmulsq(long lsqi, long *lsqa, long *lsqb)
{
long lsqs;
long lsqcarry;
zam_decl
if (lsqi <= 0) return;
lsqs = *lsqb;
lsqcarry = 0;
lsqb++;
zam_init(*lsqb, lsqs);
lsqb++;
lsqi--;
for (; lsqi > 0; lsqi--) {
zam_loop(*lsqa, lsqcarry, *lsqb);
lsqa++;
lsqb++;
}
zam_finish(*lsqa, lsqcarry);
lsqa++;
*lsqa += lsqcarry;
}
#endif
/*
* definition of zsubmul for the various long integer implementation options.
* Note that zsubmul is only called with a positive first argument.
*/
#if (defined(NTL_SINGLE_MUL))
#if (NTL_ARITH_RIGHT_SHIFT)
static
void zsubmul(long ams, long *ama, long *amb)
{
long carry = 0;
long i = (*amb++);
double dams = (double) ams;
double xx;
double yy;
unsigned long lo_wd, lo;
unsigned long hi_wd, hi;
xx = ((double) (*amb++))*dams + DENORMALIZE;
for (; i > 1; i--) {
yy = ((double) (*amb++))*dams +DENORMALIZE;
NTL_FetchHiLo(hi_wd, lo_wd, xx);
lo = lo_wd & 0x3FFFFFF;
hi = ((hi_wd<<6)|(lo_wd>>26)) & 0x3FFFFFF;
lo = (*ama) + carry - lo;
*ama = lo & 0x3FFFFFF;
carry = (((long)lo) >> 26) - hi;
ama++;
xx = yy;
}
NTL_FetchHiLo(hi_wd, lo_wd, xx);
lo = lo_wd & 0x3FFFFFF;
hi = ((hi_wd<<6)|(lo_wd>>26)) & 0x3FFFFFF;
lo = (*ama) + carry - lo;
*ama = lo & 0x3FFFFFF;
carry = (((long)lo) >> 26) - hi;
ama++;
*ama += carry;
}
#else
static
void zsubmul(long ams, long *ama, long *amb)
{
long carry = 0;
long i = (*amb++);
double dams = (double) ams;
double xx;
double yy;
unsigned long lo_wd, lo;
unsigned long hi_wd, hi;
xx = ((double) (*amb++))*dams + DENORMALIZE;
for (; i > 1; i--) {
yy = ((double) (*amb++))*dams +DENORMALIZE;
NTL_FetchHiLo(hi_wd, lo_wd, xx);
lo = lo_wd & 0x3FFFFFF;
hi = ((hi_wd<<6)|(lo_wd>>26)) & 0x3FFFFFF;
lo = (*ama) + carry - lo;
*ama = lo & 0x3FFFFFF;
carry = ((lo + (1L << 27)) >> 26) - hi - 2;
ama++;
xx = yy;
}
NTL_FetchHiLo(hi_wd, lo_wd, xx);
lo = lo_wd & 0x3FFFFFF;
hi = ((hi_wd<<6)|(lo_wd>>26)) & 0x3FFFFFF;
lo = (*ama) + carry - lo;
*ama = lo & 0x3FFFFFF;
carry = ((lo + (1L << 27)) >> 26) - hi - 2;
ama++;
*ama += carry;
}
#endif
#elif (defined(NTL_AVOID_FLOAT) || (defined(NTL_LONG_LONG) && defined(NTL_CLEAN_INT)))
static void
zsubmul(
long r,
_ntl_verylong a,
_ntl_verylong b
)
{
long rd = NTL_RADIX - r;
long i;
long carry = NTL_RADIX;
for (i = (*b++); i > 0; i--)
{
zaddmulp(*a, *b, rd, carry);
a++;
carry += NTL_RADIXM - (*b++);
}
*a += carry - NTL_RADIX; /* unnormalized */
}
#elif (defined(NTL_LONG_LONG))
/*
* NOTE: the implementation of zaddmulp for the NTL_LONG_LONG option
* will work on most machines even when the single-precision
* multiplicand is negative; however, the C language standard does
* not guarantee correct behaviour in this case, which is why the above
* implementation is used when NTL_CLEAN_INT is set.
*/
static
void zsubmul(long lams, long *lama, long *lamb)
{
long lami;
long lamcarry = 0;
lams = -lams;
for (lami = (*lamb++); lami > 0; lami--)
{
zaddmulp(*lama, *lamb, lams, lamcarry);
lama++;
lamb++;
}
*lama += lamcarry;
}
#else
/* default long integer arithmetic */
static
void zsubmul(long lams, long *lama, long *lamb)
{
long lami = (*lamb++)-1;
CARRY_TYPE lamcarry = 0;
zam_decl;
zam_init(*lamb, lams);
lamb++;
for (; lami > 0; lami--) {
zam_subloop(*lama, lamcarry, *lamb);
lama++;
lamb++;
}
zam_subfinish(*lama, lamcarry);
lama++;
*lama += CARRY_CONV(lamcarry);
}
#endif
/*
*
* zdiv21 returns quot, numhigh so
*
* quot = (numhigh*NTL_RADIX + numlow)/denom;
* numhigh = (numhigh*NTL_RADIX + numlow)%denom;
* Assumes 0 <= numhigh < denom < NTL_RADIX and 0 <= numlow < NTL_RADIX.
*/
#if (defined(NTL_CLEAN_INT))
/*
* This "clean" version relies on the guaranteed semantics of
* unsigned integer arithmetic.
*/
#define zdiv21(numhigh, numlow, denom, deninv, quot) \
{ \
unsigned long udenom = denom; \
unsigned long lq21 = (long) (((NTL_FRADIX * (double) (numhigh)) + \
(double) (numlow)) * (deninv)); \
unsigned long lr21 = (((unsigned long) numhigh) << NTL_NBITS) + \
((unsigned long) numlow) - udenom*lq21 ; \
\
if (lr21 >> (NTL_BITS_PER_LONG-1)) { \
lq21--; \
lr21 += udenom; \
} \
else if (lr21 >= udenom) { \
lr21 -= udenom; \
lq21++; \
} \
quot = (long) lq21; \
numhigh = (long) lr21; \
}
#else
/*
* This "less clean" version relies on wrap-around semantics for
* signed integer arithmetic.
*/
#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) { \
lq21--; \
lr21 += denom; \
} \
else if (lr21 >= denom) { \
lr21 -= denom; \
lq21++; \
} \
quot = lq21; \
numhigh = lr21; \
}
#endif
/*
* zrem21 behaves just like zdiv21, except the only the remainder is computed.
*/
#if (defined(NTL_CLEAN_INT) || (defined(NTL_AVOID_BRANCHING) && !NTL_ARITH_RIGHT_SHIFT))
#define NTL_CLEAN_SPMM
#endif
#if (defined(NTL_CLEAN_SPMM) && !defined(NTL_AVOID_BRANCHING))
#define zrem21(numhigh, numlow, denom, deninv) \
{ \
unsigned long udenom = denom; \
unsigned long lq21 = (long) (((NTL_FRADIX * (double) (numhigh)) + \
(double) (numlow)) * (deninv)); \
unsigned long lr21 = (((unsigned long) numhigh) << NTL_NBITS) + \
((unsigned long) numlow) - udenom*lq21 ; \
\
if (lr21 >> (NTL_BITS_PER_LONG-1)) { \
lr21 += udenom; \
} \
else if (lr21 >= udenom) { \
lr21 -= udenom; \
} \
numhigh = (long) lr21; \
}
#elif (defined(NTL_CLEAN_SPMM) && defined(NTL_AVOID_BRANCHING))
#define zrem21(numhigh, numlow, denom, deninv) \
{ \
unsigned long udenom = denom; \
unsigned long lq21 = (long) (((NTL_FRADIX * (double) (numhigh)) + \
(double) (numlow)) * (deninv)); \
unsigned long lr21 = (((unsigned long) numhigh) << NTL_NBITS) + \
((unsigned long) numlow) - udenom*lq21 ; \
lr21 += (-(lr21 >> (NTL_BITS_PER_LONG-1))) & udenom; \
lr21 -= udenom; \
lr21 += (-(lr21 >> (NTL_BITS_PER_LONG-1))) & udenom; \
numhigh = (long) lr21; \
}
#elif (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; \
}
#endif
void _ntl_zsetlength(_ntl_verylong *v, long len)
{
_ntl_verylong x = *v;
if (len < 0)
zhalt("negative size allocation in _ntl_zsetlength");
if (NTL_OVERFLOW(len, NTL_NBITS, 0))
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];
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -