This is a short selection of C code snippets that use libprimesieve to generate prime numbers.
These examples cover the most frequently used functionality of libprimesieve. Arguably the most
useful feature provided by libprimesieve is the primesieve_iterator
which lets you
iterate over primes using the primesieve_next_prime()
or primesieve_prev_prime()
functions.
Additional libprimesieve documentation links:
By default primesieve_next_prime()
generates primes > 0 i.e. 2, 3, 5, 7, ...
#include <primesieve.h>
#include <inttypes.h>
#include <stdio.h>
int main()
{
primesieve_iterator it;
primesieve_init(&it);
uint64_t sum = 0;
uint64_t prime = 0;
/* iterate over the primes < 10^9 */
while ((prime = primesieve_next_prime(&it)) < 1000000000)
sum += prime;
printf("Sum of the primes below 10^9 = %" PRIu64 "\n", sum);
primesieve_free_iterator(&it);
return 0;
}
This method changes the start number of the primesieve_iterator
object. (By
default the start number is initialized to 0). The stop_hint
parameter is
used for performance optimization, primesieve_iterator
only buffers primes
up to this limit.
#include <primesieve.h>
#include <inttypes.h>
#include <stdio.h>
int main()
{
primesieve_iterator it;
primesieve_init(&it);
/* primesieve_skipto(&it, start, stop_hint) */
primesieve_skipto(&it, 1000, 1100);
uint64_t prime;
/* iterate over primes from ]1000, 1100] */
while ((prime = primesieve_next_prime(&it)) <= 1100)
printf("%" PRIu64 "\n", prime);
primesieve_free_iterator(&it);
return 0;
}
Before using primesieve_prev_prime()
you must first change the start
number using the primesieve_skipto()
function as the start number is
initialized to 0 be default.
#include <primesieve.h>
#include <inttypes.h>
#include <stdio.h>
int main()
{
primesieve_iterator it;
primesieve_init(&it);
/* primesieve_skipto(&it, start, stop_hint) */
primesieve_skipto(&it, 2000, 1000);
uint64_t prime;
/* iterate over primes from ]2000, 1000] */
while ((prime = primesieve_prev_prime(&it)) >= 1000)
printf("%" PRIu64 "\n", prime);
primesieve_free_iterator(&it);
return 0;
}
Stores the primes inside [start, stop] in an array. The last primes type
parameter
may be one of: SHORT_PRIMES
, USHORT_PRIMES
, INT_PRIMES
, UINT_PRIMES
,
LONG_PRIMES
, ULONG_PRIMES
, LONGLONG_PRIMES
, ULONGLONG_PRIMES
,
INT16_PRIMES
, UINT16_PRIMES
, INT32_PRIMES
, UINT32_PRIMES
,
INT64_PRIMES
, UINT64_PRIMES
.
#include <primesieve.h>
#include <stdio.h>
int main()
{
uint64_t start = 0;
uint64_t stop = 1000;
size_t size;
/* Get an array with the primes inside [start, stop] */
int* primes = (int*) primesieve_generate_primes(start, stop, &size, INT_PRIMES);
for (size_t i = 0; i < size; i++)
printf("%i\n", primes[i]);
primesieve_free(primes);
return 0;
}
Stores the first n primes ≥ start in an array. The last primes type
parameter may
be one of: SHORT_PRIMES
, USHORT_PRIMES
, INT_PRIMES
, UINT_PRIMES
,
LONG_PRIMES
, ULONG_PRIMES
, LONGLONG_PRIMES
, ULONGLONG_PRIMES
,
INT16_PRIMES
, UINT16_PRIMES
, INT32_PRIMES
, UINT32_PRIMES
,
INT64_PRIMES
, UINT64_PRIMES
.
#include <primesieve.h>
#include <stdio.h>
int main()
{
uint64_t n = 1000;
uint64_t start = 0;
/* Get an array with the first 1000 primes */
int64_t* primes = (int64_t*) primesieve_generate_n_primes(n, start, INT64_PRIMES);
for (size_t i = 0; i < n; i++)
printf("%li\n", primes[i]);
primesieve_free(primes);
return 0;
}
Counts the primes inside [start, stop]. This method is multi-threaded and uses all available CPU cores by default.
#include <primesieve.h>
#include <inttypes.h>
#include <stdio.h>
int main()
{
/* primesieve_count_primes(start, stop) */
uint64_t count = primesieve_count_primes(0, 1000);
printf("Primes below 1000 = %" PRIu64 "\n", count);
return 0;
}
This method finds the nth prime e.g. nth_prime(25) = 97
. This method is
multi-threaded and uses all available CPU cores by default.
#include <primesieve.h>
#include <inttypes.h>
#include <stdio.h>
int main()
{
/* primesieve_nth_prime(n, start) */
uint64_t n = 25;
uint64_t prime = primesieve_nth_prime(n, 0);
printf("%" PRIu64 "th prime = %" PRIu64 "\n", n, prime);
return 0;
}
If an error occurs, libprimesieve functions with a uint64_t
return type return
PRIMESIEVE_ERROR
(which is defined as UINT64_MAX
in <primesieve.h>
)
and the corresponding error message is printed to the standard error stream.
#include <primesieve.h>
#include <inttypes.h>
#include <stdio.h>
int main()
{
uint64_t count = primesieve_count_primes(0, 1000);
if (count != PRIMESIEVE_ERROR)
printf("Primes below 1000 = %" PRIu64 "\n", count);
else
printf("Error in libprimesieve!\n");
return 0;
}
libprimesieve also sets the C errno
variable to EDOM
if an error
occurs. This makes it possible to check if an error has occurred in libprimesieve
functions with a void
return type. errno
is also useful for checking
after a computation that no error has occurred, this way you don't have to
check the return value of every single primesieve function call.
#include <primesieve.h>
#include <errno.h>
#include <inttypes.h>
#include <stdio.h>
int main()
{
/* Reset errno before computation */
errno = 0;
primesieve_iterator it;
primesieve_init(&it);
uint64_t sum = 0;
uint64_t prime = 0;
while ((prime = primesieve_next_prime(&it)) < 1000000000)
sum += prime;
/* Check errno after computation */
if (errno != EDOM)
printf("Sum of the primes below 10^9 = %" PRIu64 "\n", sum);
else
printf("Error in libprimesieve!\n");
primesieve_free_iterator(&it);
return 0;
}
If libprimesieve is installed on your system, then you can compile any of the C example programs above using:
cc -O3 primes.c -o primes -lprimesieve
If you have built libprimesieve yourself,
then the default installation path is usually /usr/local/lib
. Running
the ldconfig
program after make install
ensures that Linux's dynamic
linker/loader will find the shared primesieve library when you execute your program.
However, some OSes are missing the ldconfig
program or ldconfig
does
not include /usr/local/lib
by default. In these cases you need to export
some environment variables:
export LIBRARY_PATH=/usr/local/lib:$LIBRARY_PATH
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
export C_INCLUDE_PATH=/usr/local/include:$C_INCLUDE_PATH
cl /O2 /EHsc /MD primes.c /I "path\to\primesieve\include" /link "path\to\primesieve.lib"
If you are using the CMake build system to compile your program and
libprimesieve is installed on your
system, then you can add the following two lines to your CMakeLists.txt
to link your
program against libprimesieve.
find_package(primesieve REQUIRED)
target_link_libraries(your_program primesieve::primesieve)
To link against the static libprimesieve use:
find_package(primesieve REQUIRED static)
target_link_libraries(your_program primesieve::primesieve)
If you want to build your C program (named primes.c
) using CMake, then you can use
the minimal CMakeLists.txt
below. Note that this requires that
libprimesieve is installed on your
system. Using CMake has the advantage that you don't need to specify the libprimesieve include
path and the -lprimesieve
linker option when building your project.
# File: CMakeLists.txt
cmake_minimum_required(VERSION 3.4...3.19)
project(primes C CXX)
find_package(primesieve REQUIRED)
add_executable(primes primes.c)
target_link_libraries(primes primesieve::primesieve)
Put the CMakeLists.txt
file from above into the same directory as your primes.c
file.
Then open a terminal, cd into that directory and build your project using:
cmake . -DCMAKE_BUILD_TYPE=Release
cmake --build .
Using the MSVC compiler (Windows) the build instructions are slightly different. First you should link
against the static libprimesieve in your CMakeLists.txt
using:
find_package(primesieve REQUIRED static)
. Next open a Visual Studio Command Prompt, cd into your
project's directory and build your project using:
cmake -G "Visual Studio 16 2019" .
cmake --build . --config Release