Skip to content

Commit

Permalink
Merge pull request #1 from SamuraiDangyo/dev
Browse files Browse the repository at this point in the history
fast_primes_ll 1.1
  • Loading branch information
SamuraiDangyo authored Nov 1, 2019
2 parents b295302 + 5bf1fec commit 64ef17c
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 77 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
A fast prime number generator in C Language

### Help
> ```fast_primes_ll -h```
```fast_primes_ll -h```

### Install
> ```make install```
```make install```

### Usage
> ```fast_primes_ll -isprime 331 # for example```
```fast_primes_ll -isprime 331 # for example```
143 changes: 70 additions & 73 deletions fast_primes_ll.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,63 +17,23 @@
* If not, see <http://www.gnu.org/licenses/>.
**/

/**
* Headers
**/

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
#include <sys/time.h>
#include <limits.h>
#include <assert.h>
#include <stdbool.h>



#include "fast_primes_ll.h"

#define NAME "fast_primes_ll"
#define VERSION "1.0"
#define VERSION "1.1"
#define AUTHOR "Toni Helminen"
#define BITBOARD unsigned long long
#define MAX_TOKENS 128

/**
* Macros
**/

#define INT(a) ((int) (a))
#define DOUBLE(f) ((double) (f))
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define ULL(a) ((BITBOARD) (a))
#define FCP_ASSERT(test) if ( ! (test)) {P("fast_primes_ll Error: Line: %i", __LINE__); exit(0);}

static bool Token_ok();
static void Token_reset();
static void Token_add(const char *s);
static void P(const char *format, ...);
static void Print_primes(const int usize);
static bool User_is_prime(const int prime);
static void Add_prime(const int prime);
static int Next_prime();
static void Init_primes();
static void Bench();
static void Insert_primes(const int usize);
#define HASH_SIZE 64 /* MB / Starting size */

typedef struct {
BITBOARD *primes;
int *primes;
BITBOARD size;
int primes_n;
int count;
int last_size;
int key;
} HASHTABLE_T;

static char TOKENS[MAX_TOKENS][256] = {{0}}; // too plenty?
static char TOKENS[MAX_TOKENS][256] = {{0}};
static int TOKENS_N = 0;
static int TOKENS_I = 0;
static HASHTABLE_T HASH = {0};
Expand All @@ -93,7 +53,6 @@ static bool Equal_strings(const char *a, const char *b)
return strcmp(a, b) ? 0 : 1;
}


static BITBOARD Now()
{
static struct timeval t;
Expand Down Expand Up @@ -152,7 +111,7 @@ static bool Token_is(const char *s)
static void Token_expect(const char *s)
{
if ( ! Token_is(s)) {
P("Error: Unexpected Token: '%s'", Token_current());
P("{ Error: Unexpected Token: '%s' }", Token_current());
exit(0);
}
Token_pop();
Expand Down Expand Up @@ -208,24 +167,24 @@ static void Hashtable_set_size(const int usize /* MB */)
HASH.key <<= 1;
HASH.key >>= 1;
HASH.key -= 1; // 1000b = 8d / - 1d / 0111b = 7d
HASH.primes = (BITBOARD*) calloc(HASH.count, sizeof(BITBOARD)); // <- Cast for g++
HASH.primes = (int*) calloc(HASH.count, sizeof(int)); // <- Cast for g++
FCP_ASSERT(HASH.primes != NULL) // Make sure there is enough space
Init_primes();
}

static void Hashtable_make_bigger()
{
HASH.count = 2 * HASH.count;
HASH.primes = (BITBOARD*) realloc(&HASH, HASH.count * sizeof(BITBOARD)); // <- Cast for g++
HASH.primes = (int*) realloc(&HASH, HASH.count * sizeof(int)); // <- Cast for g++
}

static void System()
{
P("{ # Hash");
P(" HASH.primes_n = %i,", HASH.primes_n);
P(" HASH.size = %i MB,", (HASH.count * (sizeof(BITBOARD))) / (1024 * 1024));
P(" HASH.count = %i,", HASH.count);
P(" HASH.key = %i}", HASH.key);
P(" HASH.size = %i # MB,", (HASH.count * (sizeof(BITBOARD))) / (1024 * 1024));
P(" HASH.count = %i,", HASH.count);
P(" HASH.key = %i", HASH.key);
P("}");
}

Expand All @@ -236,7 +195,6 @@ static void Print_version()
P(" version = %s,", VERSION);
P(" author = %s,", AUTHOR);
P(" description = fast_primes_ll, A fast prime number generator in C Language");

P("}");
}

Expand All @@ -249,17 +207,18 @@ static void Print_help()
P(" fast_primes_ll -isprime 882 # is it a prime?");
P("}");
P("");
P("{ # fast_primes_ll commands");
P("{ # Commands");
P(" -h(elp) = This help,");
P(" -v(ersion) = Version,");
P(" -bench = Benchmark fast_primes_ll,");
P(" -system = System info,");
P(" -isprime [NUM] = Check if whether this number is a prime,");
P(" -isprime [NUM] = Check if whether N is a prime,");
P(" -nthprime [NUM] = Get N:th prime,");
P(" -list [NUM] = Print all primes up to N");
P("}");
P("");
P("{ # Full source code, please see");
P(" <https://github.com/SamuraiDangyo/fastprimes/>");
P("{ # Full source code, please see:");
P(" <https://github.com/SamuraiDangyo/fast_primes_ll/>");
P("}");
exit(0);
}
Expand All @@ -273,6 +232,27 @@ static void Command_isprime()
P("{ No, %i is not a prime number. }", n);
}

static int Nth_prime(const int prime_n)
{
int n = Max(0, prime_n);
if (n < HASH.primes_n)
return HASH.primes[n];
while (1) {
Add_prime(Next_prime());
if (HASH.primes_n == n)
return Last_prime();
}
}

static void Command_nthprime()
{
int n = Token_next_int();
P("{ # Results nthprime");
P(" N = %i,", n);
P(" nthprime = %i", Nth_prime(n - 1));
P("}");
}

static void Command_list()
{
int n = Max(10, Token_next_int());
Expand All @@ -282,9 +262,8 @@ static void Command_list()

static void Add_prime(const int prime)
{
if (HASH.primes_n >= HASH.count) {
if (HASH.primes_n >= HASH.count)
Hashtable_make_bigger();
}
HASH.primes[HASH.primes_n] = prime;
HASH.primes_n++;
}
Expand Down Expand Up @@ -326,14 +305,12 @@ static int Next_prime()
{
int candidate = Last_prime() + 1;
while (1) {
if (Is_prime(candidate)) {
if (Is_prime(candidate))
return candidate;
} else {
else
candidate++;
}
}
FCP_ASSERT(0)
return 0;
}

static void Insert_primes(const int usize)
Expand All @@ -354,17 +331,23 @@ static void Init_primes()
static void Bench()
{
int i;
P("> Benching ...");
P("> Benching ...\n");
BITBOARD diff;
BITBOARD start = Now();
HASH.primes_n = 0; // Just for benching
Add_prime(2);
Add_prime(3);
for (i = 0; i < 30000; i++)
for (i = 0; i < 100000; i++) {
if ((i + 1) % 10000 == 0)
P("{ done = %i%% }", (i + 1) / 1000);
Add_prime(Next_prime());
}
diff = Now() - start;
P("{ # Results");
P(" time = %.3fs,\n primes_per_second = %llu\n}", 0.001f * DOUBLE(diff), Nps(HASH.primes_n, diff));
P("");
P("{ # Benchmarks");
P(" time = %.3fs,", 0.001f * DOUBLE(diff));
P(" primes_per_second = %llu", Nps(HASH.primes_n, diff));
P("}");
}

static void Print_primes(const int usize)
Expand Down Expand Up @@ -393,6 +376,8 @@ static void FCP_commands()
System();
else if (Token_next("list"))
Command_list();
else if (Token_next("nthprime"))
Command_nthprime();
Token_expect(";");
}
if (TOKENS_N < 2)
Expand All @@ -403,7 +388,6 @@ static void Init_tokens(int argc, char **argv)
{
int i;
Token_reset();
// "-koth -perft 5" -> "; koth ; perft 5 ;"
for (i = 1 /* skip ./fast_primes_ll */; i < argc; i++) {
if (argv[i][0] == '-' && strlen(argv[i]) > 1) {
Token_add(";");
Expand All @@ -413,15 +397,28 @@ static void Init_tokens(int argc, char **argv)
}
}
Token_add(";");
// Debug_tokens();
}

static void Ok()
{
FCP_ASSERT(User_is_prime(37));
FCP_ASSERT(User_is_prime(53));
FCP_ASSERT(Nth_prime(17) == 59);
FCP_ASSERT(Nth_prime(34) == 139);
}

static void Go()
{
Hashtable_set_size(HASH_SIZE);
Init_primes();
Ok();
FCP_commands();
}

int main(int argc, char **argv)
{
atexit(Free_memory); // No memory leaks
Init_tokens(argc, argv);
Hashtable_set_size(64); // 64MB | Starting size
Init_primes();
FCP_commands();
Go();
return EXIT_SUCCESS;
}
}
63 changes: 63 additions & 0 deletions fast_primes_ll.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#ifndef FAST_PRIMES_LL_H
#define FAST_PRIMES_LL_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <sys/time.h>
#include <stdbool.h>

#define BITBOARD unsigned long long
#define MAX_TOKENS 128

#define INT(a) ((int) (a))
#define DOUBLE(f) ((double) (f))
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define ULL(a) ((BITBOARD) (a))
#define FCP_ASSERT(test) if ( ! (test)) {P("fast_primes_ll Error: Line: %i", __LINE__); exit(0);}

static inline /* <- make me faster! */ int Max(const int a, const int b);
static inline int Min(const int a, const int b);
static bool Equal_strings(const char *a, const char *b);
static BITBOARD Now();
static BITBOARD Nps(const BITBOARD nodes, const BITBOARD ms);
static void P(const char *format, ...);
static void Ok();
static void Go();
static void Token_add(const char *s);
static void Token_reset();
static const char *Token_current();
static void Token_pop();
static bool Token_ok();
static bool Token_is(const char *s);
static void Token_expect(const char *s);
static bool Token_next(const char *s);
static int Token_next_int();
static void Hashtable_free_memory();
static void Free_memory();
static void Hashtable_set_size(const int usize /* MB */);
static void Hashtable_make_bigger();
static void System();
static void Print_version();
static void Print_help();
static void Command_isprime();
static void Command_list();
static void Add_prime(const int prime);
static int Last_prime();
static bool Is_prime(const int prime);
static bool User_is_prime(const int prime);
static int Next_prime();
static void Insert_primes(const int usize);
static void Init_primes();
static void Bench();
static int Nth_prime(const int prime_n);
static void Command_nthprime();
static void Print_primes(const int usize);
static void FCP_commands();
static void Init_tokens(int argc, char **argv);

// !! i love you grandpa !!

#endif // FAST_PRIMES_LL_H
2 changes: 1 addition & 1 deletion makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
INSTALLDIR=/usr/games/

build:
gcc -Wall -O3 fast_primes_ll.c -o fast_primes_ll
gcc -Wall -O2 fast_primes_ll.c -o fast_primes_ll

clean:
rm -f fast_primes_ll
Expand Down

0 comments on commit 64ef17c

Please sign in to comment.