Here is the code, although it is not as much as fast than your one. It's just a try :
#include <iostream>
#include <limits>
#include <bitset>
using namespace std;
class BigBitSet {
private :
bitset<32> *bits;
public:
typedef unsigned long long int size_t;
explicit BigBitSet(BigBitSet::size_t size) : bits(NULL) {
BigBitSet::size_t arraySize = size / 32;
if (arraySize > numeric_limits<std::size_t>::max()) {
cout << " Array size is TOO big to allocate." << endl;
}
try {
bits = new bitset<32>[size_t(arraySize)];
}
catch(bad_alloc &) {
cout <<"Array did not allocate." << endl;
abort();
}
}
~BigBitSet() {
if (bits) {
delete bits;
}
bits = NULL;
}
inline BigBitSet& set(BigBitSet::size_t index) {
std::size_t byte = index / 32;
std::size_t bit = index % 32;
bits[byte] |= 1 << bit;
return *this;
}
inline BigBitSet& unset(BigBitSet::size_t index) {
std::size_t byte = index / 32;
std::size_t bit = index % 32;
bits[byte] &= ~(1 << bit);
return *this;
}
inline int get(BigBitSet::size_t index) const {
std::size_t byte = index / 32;
std::size_t bit = index % 32;
return bits[byte][bit];
}
};
const unsigned long long int Limit = 10000000000ULL;
const unsigned long long int SqrtLimit = 100000ULL;
const unsigned long long int ReportDepth = SqrtLimit / 100;
const unsigned long long int ReportAt = ReportDepth - 1;
const unsigned long long int FiftyBillion = 500000000ULL;
int main() {
BigBitSet isPrime(Limit);
cout << " Memory allocated." << endl;
cout << " Initialization begin";
isPrime.unset(0);
isPrime.unset(1);
isPrime.set(2);
isPrime.set(3);
for(BigBitSet::size_t i = 4; i < Limit; i++) {
if (i & 1) {
isPrime.set(i);
}
else {
isPrime.unset(i);
}
if (i % FiftyBillion == 0) {
(cout << ".").flush();
}
}
cout << endl;
cout << " Initialization done." << endl;
cout << " Calculation begin";
for(BigBitSet::size_t i = 3; i < SqrtLimit; i += 2) {
if (i % ReportDepth == ReportAt) {
(cout << ".").flush();
}
if (isPrime.get(i)) {
for(BigBitSet::size_t j = i * i; j < Limit; j += i) {
isPrime.unset(j);
}
}
}
cout << endl;
cout << " Done Calculation." << endl;
cout << " Counting begin";
BigBitSet::size_t count = 1;
for(BigBitSet::size_t i = 3; i < Limit; i += 2) {
if (isPrime.get(i)) {
count++;
}
if (i % FiftyBillion == 1) {
(cout << ".").flush();
}
}
cout << endl;
cout << " Calculated " << count << " primes upto " << Limit << endl;
return 0;
}
In this post you instructed me to optimize my code, and I try it (this is also not fast enough):
#include <iostream>
#include <vector>
#include <cmath>
#include <ctime>
#include <cstdlib>
using namespace std;
class SieveOfEratosthenes {
private :
vector<bool> *isPrime;
//bool **isPrime;
unsigned long long int Limit;
unsigned long long int sqrtLimit;
unsigned long long int ReportDepth;
unsigned long long int ReportAt;
unsigned long long int FiftyBillion;
unsigned long long int row;
unsigned long long int col;
public :
explicit SieveOfEratosthenes(unsigned long long int lim) : Limit(lim) {
sqrtLimit = (unsigned long long int)sqrt(Limit);
row = 10ULL;
col = Limit / row;
ReportDepth = sqrtLimit / 100;
ReportAt = ReportDepth - 1;
FiftyBillion = 500000000ULL;
cout << " Initializing " << endl;
try {
isPrime = new vector<bool>[row];
for (int i = 0; i < row; i++) {
isPrime[i].resize(col, true);
}
//isPrime = new bool *[row];
/*for (int i = 0; i < row; i++) {
isPrime[i] = new bool[];
}*/
}
catch (bad_alloc &) {
cout << " Initialization failed." << endl;
abort();
}
cout << " Initialization done." << endl;
}
~SieveOfEratosthenes() {
delete[] isPrime;
isPrime = NULL;
}
inline void set(unsigned long long int index, bool val) {
isPrime[index / col][index % col] = val;
}
inline bool get(unsigned long long int index) {
return isPrime[index / col][index % col];
}
void primegen() {
cout << " Prime computation started";
isPrime[0][0] = false;
isPrime[0][1] = false;
for (unsigned long long int i = 2; i < sqrtLimit; i++) {
if (get(i)) {
for (unsigned long long int j = i * i; j < Limit; j += i) {
set(j, false);
}
}
if (i % ReportDepth == ReportAt) {
(cout << ".").flush();
}
}
cout << endl;
cout << " Prime computation end." << endl;
}
void primecount() {
cout << " Prime count started";
unsigned long long int count = 0;
for (unsigned long long int i = 0; i < Limit; i++) {
if (get(i)) {
count++;
}
if (i % FiftyBillion == 1) {
(cout << ".").flush();
}
}
cout << endl;
cout << " Prime count end." << endl;
cout << " Total number of prime upto " << Limit << " : " << count << endl;
}
};
int main() {
SieveOfEratosthenes Prime(10000000000ULL);
Prime.primegen();
Prime.primecount();
return 0;
}
According to the runtime comparison the first code(1600 sec) is faster than second one(real 2500 sec).
I will wait for your response sir.

New Topic/Question
Reply




MultiQuote


|