I have written a completely working C++ program for the first time, and I have managed to compile it. I have decided to learn C++ and I have written a C++ program to familiarize myself with C++, this is my first ever C++ program and I wrote it all by myself, having only started learning a few hours prior. (And I haven't written a "Hello, World." program.)
The purpose is to practice my C++ skills and put what I have learned into use, to test if I really know the concepts I used in the script.
My idea is simple, the program accepts two command-line arguments (no std::cin
and std::cout
, I dislike interactivity), the first argument is the limit up to which primality of numbers should be checked, the second is the file path to which the prime numbers should be saved to.
The program should find all prime numbers up to the given limit using Sieve of Eratosthenes with Wheel Factorization optimization and write the prime numbers to the file line by line.
Here is the code:
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <stdexcept>
#include <vector>
const int wheel[8] = { 4, 2, 4, 2, 4, 6, 2, 6 };
const int triple[3][2] = { {4, 2}, {9, 6}, {25, 10} };
std::vector<uint64_t> wheel_sieve(uint64_t limit)
{
limit++;
std::vector<bool>is_prime(limit, true);
is_prime[0] = is_prime[1] = false;
for (auto& pair : triple)
{
int square = pair[0];
int multiple = pair[1];
for (uint64_t i = square; i < limit; i += multiple)
{
is_prime[i] = false;
}
}
uint64_t k = 7;
int i = 0;
while (true)
{
uint64_t square = k * k;
if (square > limit)
{
break;
}
if (is_prime[k])
{
uint64_t twice = 2 * k;
for (uint64_t i = square; i < limit; i += twice)
{
is_prime[i] = false;
}
}
k += wheel[i];
if (++i == 8)
{
i = 0;
}
}
std::vector<uint64_t> primes;
for (uint64_t i = 0; i < limit; i++)
{
if (is_prime[i])
{
primes.push_back(i);
}
}
return primes;
}
int main(int argc, char* argv[])
{
if (argc != 3)
{
throw std::invalid_argument("number of arguments must be 2");
}
uint64_t limit = atoi(argv[1]);
std::vector<uint64_t> primes = wheel_sieve(limit);
std::ofstream file;
file.open(argv[2]);
for (uint64_t& prime : primes)
{
file << prime << std::endl;
}
file.close();
return 0;
}
I have managed to compile it and run it, and I have confirmed its correctness. I compiled it using Visual Studio 2022 in x64 Release mode.
I guess it can be faster?:
PS C:\Users\Xeni> measure-command {C:\Users\Xeni\source\repos\Wheel_Sieve\x64\Release\Wheel_Sieve.exe 1048576 D:\primes-under-1048576.txt}
Days : 0
Hours : 0
Minutes : 0
Seconds : 0
Milliseconds : 295
Ticks : 2950071
TotalDays : 3.41443402777778E-06
TotalHours : 8.19464166666667E-05
TotalMinutes : 0.004916785
TotalSeconds : 0.2950071
TotalMilliseconds : 295.0071
How can I make it more efficient?
i
in the for loops as iteration variable, but I also usedi
in the while loop, and one of the for loops is nested inside the while loop, it may change the variable of the outer while loop and break my algorithm, but somehow it works, so it seems in C++ variables declared in for loops are private unlike Python, but it definitely was an oversight by me. \$\endgroup\$