Пример #1
0
void auxmulg(giant a, giant b)
/* Optimized general multiply, b becomes a*b. Modes are:
* AUTO_MUL: switch according to empirical speed criteria.
* GRAMMAR_MUL: force grammar-school algorithm.
* KARAT_MUL: force Karatsuba divide-conquer method.
* FFT_MUL: force floating point FFT method. */
{
	float		grammartime;
	int 		square = (a == b);
	int 		sizea, sizeb;

	switch (mulmode)
	{
		case GRAMMAR_MUL:
			if (square) grammarsquareg(b);
			else grammarmulg(a, b);
			break;
		case FFT_MUL:
			if (square)
				FFTsquareg(b);
			else
				FFTmulg(a, b);
			break;
		case KARAT_MUL:
			if (square) karatsquareg(b);
			else karatmulg(a, b);
			break;
		case AUTO_MUL:
			sizea = abs(a->sign);
			sizeb = abs(b->sign);
			if ((sizea > KARAT_BREAK) && (sizea <= FFT_BREAK) &&
				(sizeb > KARAT_BREAK) && (sizeb <= FFT_BREAK)) {
				if (square) karatsquareg(b);
				else karatmulg(a, b);

			}
			else {
				grammartime = (float)sizea;
				grammartime *= (float)sizeb;
				if (grammartime < FFT_BREAK * FFT_BREAK)
				{
					if (square) grammarsquareg(b);
					else grammarmulg(a, b);
				}
				else
				{
					if (square) FFTsquareg(b);
					else FFTmulg(a, b);
				}
			}
			break;
	}
}
Пример #2
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);
}
Пример #3
0
void FFTsquareg(giant x)
{
	int 			j, size = abs(x->sign);
	register int 	L;

	if (size < 4)
	{
		grammarmulg(x, x);
		return;
	}
	L = lpt(size + size, &j);
	if (!z) z = (double *)malloc(MAX_SHORTS * sizeof(double));
	giant_to_double(x, size, z, L);
	fft_real_to_hermitian(z, L);
	square_hermitian(z, L);
	fftinv_hermitian_to_real(z, L);
	addsignal(x, z, L);
	x->sign = abs(x->sign);
}
Пример #4
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");
}