Compare commits
17 Commits
Author | SHA1 | Date | |
---|---|---|---|
a9019291c2 | |||
5aa0b333c0 | |||
3110c74174 | |||
a5ce845c68 | |||
449fef2994 | |||
2e9326b5fb | |||
06cb271dba | |||
4cbc3fae7d | |||
9b4fa96474 | |||
e2aedab3b0 | |||
bc8b48dd29 | |||
dab78093ab | |||
a782bdb57d | |||
9157d15383 | |||
f1fd758bfc | |||
66c0a5d027 | |||
f4ee9872bc |
@ -17,4 +17,4 @@ build:
|
|||||||
# Cache .o files for faster compiling
|
# Cache .o files for faster compiling
|
||||||
cache:
|
cache:
|
||||||
paths:
|
paths:
|
||||||
- "*.o"
|
- "build/CMakeFiles/indivisible.dir/src/*.o"
|
||||||
|
10
CHANGELOG
10
CHANGELOG
@ -9,3 +9,13 @@ Change Log
|
|||||||
- Switch to C.
|
- Switch to C.
|
||||||
- Uses GNU Multiple Precision library (GMP) to hold prime numbers, allowing for 'infinite' size.
|
- Uses GNU Multiple Precision library (GMP) to hold prime numbers, allowing for 'infinite' size.
|
||||||
- Add `likely()' and `unlikely()' macros to optimize.
|
- Add `likely()' and `unlikely()' macros to optimize.
|
||||||
|
- v0.2.1: Memory Leak Fixes
|
||||||
|
- Fixed a major memory leak at the end of the program.
|
||||||
|
- Added more optimizers.
|
||||||
|
- v0.3: Optimizations
|
||||||
|
- Algorithm skips half the known primes.
|
||||||
|
- Removed `likely()' and `unlikely()' macros due to lack of information.
|
||||||
|
- Improved performance.
|
||||||
|
- v0.4: Fixed Algorithm
|
||||||
|
- Fixed algorithm to actually calculate primes.
|
||||||
|
- Added extra C99 optimizations.
|
||||||
|
12
src/list.c
12
src/list.c
@ -2,15 +2,13 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "optimizers.h"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the number of elements by which the list expands.
|
* This is the number of elements by which the list expands.
|
||||||
* WARNING: Always use doubles for this number (2^X)
|
* WARNING: Always use doubles for this number (2^X)
|
||||||
*/
|
*/
|
||||||
#define BLOCK_SIZE 1024
|
#define BLOCK_SIZE 1024
|
||||||
|
|
||||||
void initList(List *l) {
|
void initList(List *restrict l) {
|
||||||
l->list = malloc(sizeof(mpz_t) * BLOCK_SIZE);
|
l->list = malloc(sizeof(mpz_t) * BLOCK_SIZE);
|
||||||
if(!l->list) {
|
if(!l->list) {
|
||||||
fprintf(stderr, "Failed to allocate memory to list!\n");
|
fprintf(stderr, "Failed to allocate memory to list!\n");
|
||||||
@ -20,7 +18,7 @@ void initList(List *l) {
|
|||||||
l->end = 0;
|
l->end = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void deInitList(List *l) {
|
void deInitList(List *restrict l) {
|
||||||
for(ulli i = 0; i < l->size; ++i) {
|
for(ulli i = 0; i < l->size; ++i) {
|
||||||
mpz_clear(l->list[i]);
|
mpz_clear(l->list[i]);
|
||||||
}
|
}
|
||||||
@ -28,14 +26,14 @@ void deInitList(List *l) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void addToList(List *l, mpz_t n) {
|
void addToList(List *l, mpz_t n) {
|
||||||
if(unlikely(l->end == l->size)) {
|
if(l->end == l->size) {
|
||||||
l->size += BLOCK_SIZE;
|
l->size += BLOCK_SIZE;
|
||||||
if(unlikely(l->size == 0)) {
|
if(l->size == 0) {
|
||||||
fprintf(stderr, "`l->size' has overflowed!\n");
|
fprintf(stderr, "`l->size' has overflowed!\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
void *tmp = realloc(l->list, sizeof(mpz_t) * l->size);
|
void *tmp = realloc(l->list, sizeof(mpz_t) * l->size);
|
||||||
if(unlikely(!tmp)) {
|
if(!tmp) {
|
||||||
fprintf(stderr, "Failed to allocate more memory to list!\n");
|
fprintf(stderr, "Failed to allocate more memory to list!\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -20,14 +20,14 @@ typedef struct {
|
|||||||
* failure.
|
* failure.
|
||||||
* @param[in] l A pointer to a List type to be initialized.
|
* @param[in] l A pointer to a List type to be initialized.
|
||||||
*/
|
*/
|
||||||
void initList(List *l);
|
void initList(List *restrict l);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Deinitialize a List.
|
* @brief Deinitialize a List.
|
||||||
* @details Release all memory that has been allocated to the list.
|
* @details Release all memory that has been allocated to the list.
|
||||||
* @param[in] l A pointer to a List type to be deinitialized.
|
* @param[in] l A pointer to a List type to be deinitialized.
|
||||||
*/
|
*/
|
||||||
void deInitList(List *l);
|
void deInitList(List *restrict l);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Adds a new item to a List type.
|
* @brief Adds a new item to a List type.
|
||||||
|
20
src/main.c
20
src/main.c
@ -6,13 +6,12 @@
|
|||||||
|
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "optimizers.h"
|
|
||||||
|
|
||||||
static bool run;
|
static bool run;
|
||||||
void leave();
|
void leave();
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
printf("Indivisible v0.2\n");
|
puts("Indivisible v0.4\n");
|
||||||
|
|
||||||
// Quit on ^C by setting `run = false'
|
// Quit on ^C by setting `run = false'
|
||||||
run = true;
|
run = true;
|
||||||
@ -36,9 +35,16 @@ int main(void) {
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
mpz_add_ui(num, num, 1);
|
mpz_add_ui(num, num, 1);
|
||||||
|
|
||||||
|
// Variable for half `num'
|
||||||
|
mpz_t halfNum;
|
||||||
|
mpz_init(halfNum);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
// Calculate half of `num'
|
||||||
|
mpz_fdiv_q_ui(halfNum, num, 2);
|
||||||
// Loop through found primes
|
// Loop through found primes
|
||||||
for(ulli i = 0; i < primes.size; ++i) {
|
for(ulli i = 0; i < primes.end; ++i) {
|
||||||
|
if(mpz_cmp(primes.list[i], halfNum) >= 0) break;
|
||||||
// If `num' is divisible by a prime then go to the next number
|
// If `num' is divisible by a prime then go to the next number
|
||||||
if(mpz_divisible_p(num, primes.list[i]) != 0)
|
if(mpz_divisible_p(num, primes.list[i]) != 0)
|
||||||
goto nextPrime;
|
goto nextPrime;
|
||||||
@ -46,7 +52,7 @@ int main(void) {
|
|||||||
|
|
||||||
// `num' is a prime so we add it to the list and print it
|
// `num' is a prime so we add it to the list and print it
|
||||||
addToList(&primes, num);
|
addToList(&primes, num);
|
||||||
if(unlikely(mpz_out_str(stdout, 10, num) == 0)) {
|
if(mpz_out_str(stdout, 10, num) == 0) {
|
||||||
fprintf(stderr, "Could not print to `stdout'!\n");
|
fprintf(stderr, "Could not print to `stdout'!\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@ -55,8 +61,10 @@ int main(void) {
|
|||||||
nextPrime:
|
nextPrime:
|
||||||
// Add 2 (skip even numbers since they're all divisible by 2)
|
// Add 2 (skip even numbers since they're all divisible by 2)
|
||||||
mpz_add_ui(num, num, 2);
|
mpz_add_ui(num, num, 2);
|
||||||
} while(likely(run));
|
} while(run);
|
||||||
|
|
||||||
|
// Clear GMP variables
|
||||||
|
mpz_clear(halfNum);
|
||||||
mpz_clear(num);
|
mpz_clear(num);
|
||||||
// Deinitialize the list
|
// Deinitialize the list
|
||||||
deInitList(&primes);
|
deInitList(&primes);
|
||||||
@ -64,6 +72,6 @@ nextPrime:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void leave() {
|
void leave() {
|
||||||
printf("Exiting...\n");
|
puts("Exiting...\n");
|
||||||
run = false;
|
run = false;
|
||||||
}
|
}
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#define likely(x) __builtin_expect(!!(x), 1)
|
|
||||||
#define unlikely(x) __builtin_expect(!!(x), 0)
|
|
Reference in New Issue
Block a user