Using a better algorithm based on property of primes.

I recently found out that `p` being prime, while `p > 3`, then
`p = 6*k (+/-) 1`.
This commit is contained in:
Nicolás Ortega Froysa 2019-10-08 17:58:08 +02:00
parent 2cfc24afb7
commit 84687f86c1
4 changed files with 84 additions and 22 deletions

View File

@ -22,7 +22,7 @@ LDFLAGS=-lgmp
DEFS=-DVERSION=\"2.0\" -DAPP_NAME=\"Indivisible\"
CFLAGS=$(INCFLAGS) $(DEFS) -std=c99 -Wall -Wextra -Wfatal-errors -Werror
HDRS=src/globals.h src/llist.h
OBJS=src/main.o src/llist.o
OBJS=src/llist.o src/main.o src/prime_test.o
ifeq ($(DEBUG),1)
CFLAGS+=-g -O0 -DDEBUG

View File

@ -18,6 +18,7 @@
#include "globals.h"
#include "llist.h"
#include "prime_test.h"
#include <signal.h>
#include <stdio.h>
@ -35,40 +36,35 @@ int main() {
signal(SIGINT, quit_signal);
mpz_t tnum; // number to be tested for prime-ness
mpz_t tsqrt; // square root of tnum
mpz_t aux; // auxilary number to test against tnum
mpz_t r; // remainder from modulus operation
mpz_t test_base; // number used to get tested numbers
mpz_t p0, p1; // numbers to be tested for prime-ness.
mpz_inits(tnum, tsqrt, aux, r, NULL);
mpz_set_ui(tnum, 3);
mpz_sqrt(tsqrt, tnum);
mpz_inits(test_base, p0, p1, NULL);
mpz_set_ui(test_base, 6);
puts("2");
puts("3");
while(run)
{
mpz_set_ui(aux, 3);
int is_prime = 1;
while(mpz_cmp(aux, tsqrt) <= 0)
{
mpz_mod(r, tnum, aux);
if(mpz_cmp_ui(r, 0) == 0)
is_prime = 0;
mpz_add_ui(aux, aux, 2);
}
mpz_sub_ui(p0, test_base, 1); // p0 = test_base - 1
mpz_add_ui(p1, test_base, 1); // p0 = test_base + 1
if(is_prime)
if(test_prime(p0))
{
mpz_out_str(stdout, 10, tnum);
mpz_out_str(stdout, 10, p0);
printf("\n");
}
if(test_prime(p1))
{
mpz_out_str(stdout, 10, p1);
printf("\n");
}
mpz_add_ui(tnum, tnum, 2);
mpz_sqrt(tsqrt, tnum);
mpz_add_ui(test_base, test_base, 6);
}
mpz_clears(tnum, tsqrt, aux, r, NULL);
mpz_clears(test_base, p0, p1, NULL);
return 0;
}

39
src/prime_test.c Normal file
View File

@ -0,0 +1,39 @@
/*
* Copyright (C) 2019 Ortega Froysa, Nicolás <nicolas@ortegas.org>
* Author: Ortega Froysa, Nicolás <nicolas@ortegas.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "prime_test.h"
int test_prime(const mpz_t p) {
mpz_t psqrt;
mpz_t aux;
mpz_inits(psqrt, aux, NULL);
mpz_sqrt(psqrt, p);
int is_prime = 1;
for(mpz_set_ui(aux, 5); mpz_cmp(aux, psqrt) <= 0; mpz_add_ui(aux, aux, 2))
{
if(mpz_divisible_p(p, aux))
{
is_prime = 0;
break;
}
}
mpz_clears(psqrt, aux, NULL);
return is_prime;
}

27
src/prime_test.h Normal file
View File

@ -0,0 +1,27 @@
/*
* Copyright (C) 2019 Ortega Froysa, Nicolás <nicolas@ortegas.org>
* Author: Ortega Froysa, Nicolás <nicolas@ortegas.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <gmp.h>
/*
* checks to see if the number `p` is prime, returning 1 if it is and 0
* if it is not.
*/
int test_prime(const mpz_t p);