Exemple #1
0
void FFTmulg(giant y, giant x)
{
	/* x becomes y*x. */
	int 			lambda, sizex = abs(x->sign), sizey = abs(y->sign);
	int 			finalsign = gsign(x)*gsign(y);
	register int	L;

	if ((sizex <= 4) || (sizey <= 4))
	{
		grammarmulg(y, x);
		return;
	}
	L = lpt(sizex + sizey, &lambda);
	if (!z) z = (double *)malloc(MAX_SHORTS * sizeof(double));
	if (!z2) z2 = (double *)malloc(MAX_SHORTS * sizeof(double));

	giant_to_double(x, sizex, z, L);
	giant_to_double(y, sizey, z2, L);
	fft_real_to_hermitian(z, L);
	fft_real_to_hermitian(z2, L);
	mul_hermitian(z2, z, L);
	fftinv_hermitian_to_real(z, L);
	addsignal(x, z, L);
	x->sign = finalsign * abs(x->sign);
}
void
gmersennemod(
	int 	n,
	giant 	g
)
/* g := g (mod 2^n - 1) */
{
    int the_sign;
    giant scratch3 = borrowGiant(g->capacity);
    giant scratch4 = borrowGiant(1);

    if ((the_sign = gsign(g)) < 0) absg(g);
    while (bitlen(g) > n) {
	gtog(g,scratch3);
	gshiftright(n,scratch3);
	addg(scratch3,g);
	gshiftleft(n,scratch3);
	subg(scratch3,g);
    }
    if(isZero(g)) goto out;
    int_to_giant(1,scratch3);
    gshiftleft(n,scratch3);
    int_to_giant(1,scratch4);
    subg(scratch4,scratch3);
    if(gcompg(g,scratch3) >= 0) subg(scratch3,g);
    if (the_sign < 0) {
	g->sign = -g->sign;
	addg(scratch3,g);
    }
out:
    returnGiant(scratch3);
    returnGiant(scratch4);
}
Exemple #3
0
void grammarmulg(giant a, giant b)
/* b becomes a*b. */
{
	int 			i, j;
	unsigned int 	prod, carry = 0;
	int 			asize = abs(a->sign), bsize = abs(b->sign);
	unsigned short 	*aptr, *bptr, *destptr;
	unsigned short	mult;
	giant scratch = popg();

	for (i = 0; i < asize + bsize; ++i)
	{
		scratch->n[i] = 0;
	}

	bptr = &(b->n[0]);
	for (i = 0; i < bsize; ++i)
	{
		mult = *(bptr++);
		if (mult)
		{
			carry = 0;
			aptr = &(a->n[0]);
			destptr = &(scratch->n[i]);
			for (j = 0; j < asize; ++j)
			{
				prod = *(aptr++) * mult + *destptr + carry;
				*(destptr++) = (unsigned short)(prod & 0xffff);
				carry = prod >> 16;
			}
			*destptr = (unsigned short)carry;
		}
	}
	bsize += asize;
	if (!carry)
		--bsize;
	scratch->sign = gsign(a)*gsign(b)*bsize;
	gtog(scratch, b);
	pushg(1);
}
Exemple #4
0
void gshiftleft(int	bits, giant g)
/* shift g left bits bits. Equivalent to g = g*2^bits. */
{
	int 			rem = bits & 15, crem = 16 - rem, words = bits >> 4;
	int 			size = abs(g->sign), j, k, sign = gsign(g);
	unsigned short 	carry, dat;

	if (!bits)
		return;
	if (!size)
		return;
	if (bits < 0) {
		gshiftright(-bits, g);
		return;
	}
	if (size + words + 1 > current_max_size) {
		error = OVFLOW;
		exit(error);
	}
	if (rem == 0) {
		memmove(g->n + words, g->n, size * sizeof(short));
		for (j = 0; j < words; j++) g->n[j] = 0;
		g->sign += (g->sign < 0) ? (-words) : (words);
	}
	else {
		k = size + words;
		carry = 0;
		for (j = size - 1; j >= 0; j--) {
			dat = g->n[j];
			g->n[k--] = (unsigned short)((dat >> crem) | carry);
			carry = (unsigned short)(dat << rem);
		}
		do {
			g->n[k--] = carry;
			carry = 0;
		} while (k >= 0);

		k = size + words;
		if (g->n[k] == 0)
			--k;
		g->sign = sign * (k + 1);
	}
}
void gshiftleft(int bits, giant g) {
/* shift g left bits bits.  Equivalent to g = g*2^bits */
    int 	rem = bits & (GIANT_BITS_PER_DIGIT - 1);
    int 	crem = GIANT_BITS_PER_DIGIT - rem;
    int 	digits = 1 + (bits >> GIANT_LOG2_BITS_PER_DIGIT);
    int 	size = abs(g->sign);
    int 	j;
    int 	k;
    int 	sign = gsign(g);
    giantDigit 	carry;
    giantDigit 	dat;

    #if		FEE_DEBUG
    if(bits < 0) {
        CKRaise("gshiftleft(-bits)\n");
    }
    #endif	/* FEE_DEBUG */

    if(!bits) return;
    if(!size) return;
    if((size+digits) > (int)g->capacity) {
        CKRaise("gshiftleft overflow");
        return;
    }
    k = size - 1 + digits;	// (MSD of result + 1)
    carry = 0;

    /* bug fix for 32-bit giantDigits; this is also an optimization for
     * other sizes. rem=0 means we're shifting strictly by digits, no
     * bit shifts. */
    if(rem == 0) {
        g->n[k] = 0;		// XXX hack - for sign fixup
	for(j=size-1; j>=0; j--) {
	    g->n[--k] = g->n[j];
	}
	do{
	    g->n[--k] = 0;
	} while(k>0);
    }
    else {
    	/*
	 * normal unaligned case
	 * FIXME - this writes past g->n[size-1] the first time thru!
	 */
	for(j=size-1; j>=0; j--) {
	    dat = g->n[j];
	    g->n[k--] = (dat >> crem) | carry;
	    carry = (dat << rem);
	}
	do{
	    g->n[k--] = carry;
	    carry = 0;
	} while(k>=0);
    }
    k = size - 1 + digits;
    if(g->n[k] == 0) --k;
    g->sign = sign * (k+1);
    if (abs(g->sign) > g->capacity) {
    	CKRaise("gshiftleft overflow");
    }
}