Пример #1
0
void iaddg(int	i, giant g)
/* Giant g becomes g + (int)i. */
{
	int 	w, j = 0, carry = 0, size = abs(g->sign);
	giant	tmp;

	if (isZero(g))
	{
		itog(i, g);
	}
	else if (g->sign < 0) {
		tmp = popg();
		itog(i, tmp);
		addg(tmp, g);
		pushg(1);
		return;
	}
	else
	{
		w = g->n[0] + i;
		do
		{
			g->n[j] = (unsigned short)(w & 65535L);
			carry = w >> 16;
			w = g->n[++j] + carry;
		} while ((carry != 0) && (j < size));
	}
	if (carry)
	{
		++g->sign;
		g->n[size] = (unsigned short)carry;
	}
}
Пример #2
0
void make_recip(giant d, giant r)
/* r becomes the steady-state reciprocal
* 2^(2b)/d, where b = bit-length of d-1. */
{
	int		b;
	giant 	tmp, tmp2;

	if (isZero(d) || (d->sign < 0))
	{
		exit(SIGN);
	}
	tmp = popg();
	tmp2 = popg();
	itog(1, r);
	subg(r, d);
	b = bitlen(d);
	addg(r, d);
	gshiftleft(b, r);
	gtog(r, tmp2);
	while (1)
	{
		gtog(r, tmp);
		squareg(tmp);
		gshiftright(b, tmp);
		mulg(d, tmp);
		gshiftright(b, tmp);
		addg(r, r);
		subg(tmp, r);
		if (gcompg(r, tmp2) <= 0)
			break;
		gtog(r, tmp2);
	}
	itog(1, tmp);
	gshiftleft(2 * b, tmp);
	gtog(r, tmp2);
	mulg(d, tmp2);
	subg(tmp2, tmp);
	itog(1, tmp2);
	while (tmp->sign < 0)
	{
		subg(tmp2, r);
		addg(d, tmp);
	}
	pushg(2);
}
Пример #3
0
void grammarsquareg(giant a)
/* a := a^2. */
{
	unsigned int	cur_term;
	unsigned int	prod, carry = 0, temp;
	unsigned int	asize = abs(a->sign), max = asize * 2 - 1;
	unsigned short	*ptr = a->n, *ptr1, *ptr2;
	giant scratch;

	if (asize == 0) {
		itog(0, a);
		return;
	}

	scratch = popg();

	asize--;

	temp = *ptr;
	temp *= temp;
	scratch->n[0] = temp;
	carry = temp >> 16;

	for (cur_term = 1; cur_term < max; cur_term++) {
		ptr1 = ptr2 = ptr;
		if (cur_term <= asize) {
			ptr2 += cur_term;
		}
		else {
			ptr1 += cur_term - asize;
			ptr2 += asize;
		}
		prod = carry & 0xFFFF;
		carry >>= 16;
		while (ptr1 < ptr2) {
			temp = *ptr1++ * *ptr2--;
			prod += (temp << 1) & 0xFFFF;
			carry += (temp >> 15);
		}
		if (ptr1 == ptr2) {
			temp = *ptr1;
			temp *= temp;
			prod += temp & 0xFFFF;
			carry += (temp >> 16);
		}
		carry += prod >> 16;
		scratch->n[cur_term] = (unsigned short)(prod);
	}
Пример #4
0
void powermodg(giant x, giant n, giant g)
/* x becomes x^n (mod g). */
{
	int 		len, pos;
	giant		scratch2 = popg();

	gtog(x, scratch2);
	itog(1, x);
	len = bitlen(n);
	pos = 0;
	while (1)
	{
		if (bitval(n, pos++))
		{
			mulg(scratch2, x);
			modg(g, x);
		}
		if (pos >= len)
			break;
		squareg(scratch2);
		modg(g, scratch2);
	}
	pushg(1);
}
Пример #5
0
void
main(
	void
)
{
	giant 		x = newgiant(INFINITY), y = newgiant(INFINITY),
				p = newgiant(INFINITY), r = newgiant(100);
	int 		j;

   	printf("Give two integers x, y on separate lines:\n");
   	gin(x); 
   	gin(y); 

   	gtog(y, p);  /* p := y */
   	mulg(x, p);
   	printf("y * x = "); 
   	gout(p);

  	gtog(y, p);
   	subg(x, p);
   	printf("y - x = "); 
   	gout(p);

   	gtog(y, p);
   	addg(x, p);
   	printf("y + x = "); 
   	gout(p);

   	gtog(y, p);
   	divg(x, p);
   	printf("y div x = "); 
   	gout(p);

   	gtog(y, p);
   	modg(x, p);
   	printf("y mod x = "); 
   	gout(p);

   	gtog(y, p);
   	gcdg(x, p);
   	printf("GCD(x, y) = "); 
   	gout(p);
 
	/* Next, test which of x, y is greater. */
   	if (gcompg(x, y) < 0 ) 
   		printf("y is greater\n");
	else if (gcompg(x,y) == 0) 
		printf("x, y equal\n");
	else 
		printf("x is greater\n");

	/* Next, we see how a giant struct is comprised.
   	 * We make a random, bipolar number of about 100 
   	 * digits in base 65536. 
   	 */
	for (j=0; j < 100; j++) 
	{  /* Fill 100 digits randomly. */
		r->n[j] = (unsigned short)rand();
   	}
   	r->sign = 100 * (1 - 2*(rand()%2));

	/* Next, don't forget to check for leading zero digits,
     * even though such are unlikely. 
     */
   	j = abs(r->sign) - 1;
   	while ((r->n[j] == 0) && (j > 0)) 
   	{
   		--j;
   	}
   	r->sign = (j+1) * ((r->sign > 0) ? 1: -1);
   	printf("The random number: "); gout(r);

	/* Next, compare a large-FFT multiply with a standard,
     * grammar-school multiply. 
     */
   	itog(1, x); 
   	gshiftleft(65536, x); 
   	iaddg(1, x);
   	itog(5, y); 
   	gshiftleft(30000, y); 
   	itog(1, p); 
   	subg(p, y); 
	/* Now we multiply (2^65536 + 1)*(5*(2^30000) - 1). */
   	gtog(y, p);
   	mulg(x, p);  /* Actually invokes FFT method because
					bit lengths of x, y are sufficiently large. */
   	printf("High digit of (2^65536 + 1)*(5*(2^30000) - 1) via FFT mul: %d\n", (int) p->n[abs(p->sign)-1]);
   	fflush(stdout);
   	gtog(y, p);
   	grammarmulg(x, p);  /* Grammar-school method. */
   	printf("High digit via grammar-school mul: %d\n", (int) p->n[abs(p->sign)-1]);
   	fflush(stdout);

	/* Next, perform Fermat test for pseudoprimality. */
   	printf("Give prime candidate p:\n");
   	gin(p); 
   	gtog(p, y);
   	itog(1, x); subg(x, y);
   	itog(2, x);
   	powermodg(x, y, p);
   	if (isone(x)) 
   		printf("p is probably prime.\n");
	else 
		printf("p is composite.\n");
}