/* Copyright 2012-2015 David Cleaver
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*/
#include
#ifdef _MSC_VER
# include "gettimeofday.h"
#else
# include
#endif
#include
#include
#include "mpz_aprcl.h"
/* these are vars used to time our program */
double t0, t1, t2, t3;
int t_d;
int t_h;
int t_m;
int t_s;
double ttime(double base) {
struct timeval tod;
gettimeofday(&tod, NULL);
return tod.tv_sec + tod.tv_usec/1e6 - base;
}/* method ttime */
/***********************************************************************************/
/* returns the number of decimal digits of n */
unsigned int
b10_digits (const mpz_t n)
{
mpz_t x;
unsigned int size;
size = mpz_sizeinbase (n, 10);
/* the GMP documentation says mpz_sizeinbase returns the exact value,
or one too big, thus:
(a) either n < 10^(size-1), and n has size-1 digits
(b) or n >= size-1, and n has size digits
Note: mpz_sizeinbase returns 1 for n=0, thus we always have size >= 1.
*/
mpz_init (x);
mpz_ui_pow_ui (x, 10, size - 1);
if (mpz_cmpabs (n, x) < 0)
size --;
mpz_clear (x);
return size;
}
/***********************************************************************************/
int main(int argc, char* argv[])
{
int ret_b = 0;
int ret_a = 0;
int dig = 0;
mpz_t test;
#define MAXDIGITS 10000
char input[MAXDIGITS];
FILE *fp;
if (argc < 2 || argc > 3)
{
printf("Usage:\n");
printf(" %s \n", argv[0]);
printf(" Where is a number to test for primality\n");
printf(" %s -inp \n", argv[0]);
printf(" Where contains one or more numbers to test for primality\n");
printf(" Note: This program returns the APR-CL and MPZ PRP status of the input number(s).\n");
printf(" Note: This program will also print out timing information for each check.\n");
printf(" Note: All input numbers are assumed to be base-10 numbers.\n");
return 0;
}
if (strcmp(argv[1], "-inp") == 0)
{
fp = fopen(argv[2], "r");
if(!fp)
{
printf("Error, invalid file: %s\n", argv[2]);
return 1; // bail out if file not found
}
while(fgets(input,sizeof(input),fp) != NULL)
{
/* make sure last character is 0 (null) */
if(input[MAXDIGITS-1] != 0)
input[MAXDIGITS-1] = 0;
if (strlen(input) == 0) continue;
if (input[0] == 0xd || input[0] == 0xa) continue;
if (input[0] < '0' || input[0] > '9')
{
printf("\n *** Notice, not testing the following line:\n");
printf("%s\n", input);
continue;
}
if (mpz_init_set_str(test, input, 10) < 0)
{
printf(" *** ERROR, invalid number: %s\n", input);
continue;
}
printf("===============================================================================\n");
dig = b10_digits(test);
gmp_printf("Testing: %Zd (%d digits)\n", test, dig); fflush(stdout);
printf("Running the MPZ PRP test with 5 iterations...\n"); fflush(stdout);
t0 = ttime(0);
ret_b = mpz_probab_prime_p(test, 5);
t1 = ttime(t0);
printf("Running the APRCL prime test...\n"); fflush(stdout);
t0 = ttime(0);
ret_a = mpz_aprtcle(test, 1);
t2 = ttime(t0);
printf("\n MPZ PRP took %.4f seconds\n", t1);
if (ret_b == APRTCLE_COMPOSITE)
printf(" MPZ PRP says the number is COMPOSITE\n");
else if (ret_b == APRTCLE_PRP)
printf(" MPZ PRP says the number is PRP\n");
else if (ret_b == APRTCLE_PRIME)
printf(" MPZ PRP says the number is PRIME\n");
printf("APRCL took %.4f seconds\n", t2);
if (ret_a == APRTCLE_COMPOSITE)
printf("APRCL says the number is COMPOSITE\n");
else if (ret_a == APRTCLE_PRP)
printf("APRCL says the number is PRP\n");
else if (ret_a == APRTCLE_PRIME)
printf("APRCL says the number is PRIME\n");
if ((ret_b == APRTCLE_COMPOSITE && ret_a != APRTCLE_COMPOSITE) ||
(ret_b != APRTCLE_COMPOSITE && ret_a == APRTCLE_COMPOSITE))
{
printf(" *** ATTENTION *** ATTENTION *** ATTENTION *** ATTENTION ***\n");
printf("MPZ PRP and APRCL do not agree on the status of this number!!!\n");
printf("Please report this to http://www.mersenneforum.org/showthread.php?t=18353\n");
gmp_printf("N = %Zd\n", test);
}
}
fclose(fp);
}
else
{
if (mpz_init_set_str(test, argv[1], 10) < 0)
{
mpz_clear(test);
printf("Error, invalid number: %s\n", argv[1]);
return 0;
}
dig = b10_digits(test);
gmp_printf("Testing: %Zd (%d digits)\n", test, dig); fflush(stdout);
printf("Running the MPZ PRP test with 5 iterations...\n"); fflush(stdout);
t0 = ttime(0);
ret_b = mpz_probab_prime_p(test, 5);
t1 = ttime(t0);
printf("Running the APRCL prime test...\n"); fflush(stdout);
t0 = ttime(0);
ret_a = mpz_aprtcle(test, 1);
t2 = ttime(t0);
printf("\n MPZ PRP took %.4f seconds\n", t1);
if (ret_b == APRTCLE_COMPOSITE)
printf(" MPZ PRP says the number is COMPOSITE\n");
else if (ret_b == APRTCLE_PRP)
printf(" MPZ PRP says the number is PRP\n");
else if (ret_b == APRTCLE_PRIME)
printf(" MPZ PRP says the number is PRIME\n");
printf("APRCL took %.4f seconds\n", t2);
if (ret_a == APRTCLE_COMPOSITE)
printf("APRCL says the number is COMPOSITE\n");
else if (ret_a == APRTCLE_PRP)
printf("APRCL says the number is PRP\n");
else if (ret_a == APRTCLE_PRIME)
printf("APRCL says the number is PRIME\n");
if ((ret_b == APRTCLE_COMPOSITE && ret_a != APRTCLE_COMPOSITE) ||
(ret_b != APRTCLE_COMPOSITE && ret_a == APRTCLE_COMPOSITE))
{
printf(" *** ATTENTION *** ATTENTION *** ATTENTION *** ATTENTION ***\n");
printf("MPZ PRP and APRCL do not agree on the status of this number!!!\n");
printf("Please report this to http://www.mersenneforum.org/showthread.php?t=18353\n");
gmp_printf("N = %Zd\n", test);
}
}
mpz_clear(test);
return 0;
}