diff --git a/data/eratosfen.c b/data/eratosfen.c new file mode 100644 index 0000000..ac02397 --- /dev/null +++ b/data/eratosfen.c @@ -0,0 +1,92 @@ +#include +#include +#define SIZE 12500000 + +int check_bit(char x, int pos); +int count_bits(char x, int max_offset); + +int main() { + /* + Info about every number is stored into BITS of char elements, so we can have 8 * SIZE numbers. Not including numbers divided by 2, they aren't prime by design. + Array start: {1, 2, 3, 5, 7 ...} at sieve[0] + */ + char *sieve = (char*)calloc(SIZE, sizeof(char)); + int N, i, j, byte, offset, in_offset, in_byte, num, byte_n; + int res = 0; + scanf("%d", &N); + int n = N; + if (N % 2) { + N = (N + 1) / 2 + 1; + } + else { + N = N / 2 + 1; + } + if (N % 8) { + byte_n = (int)(N / 8) + 1; + } + else { + byte_n = (int)(N / 8); + } +#ifdef _DEBUG + printf("byte_n[%d], N[%d]\n", byte_n, N); +#endif + /* Initialization of used numbers by 1 (bits of every char, char is 1 byte) */ + for (i = 0; i < byte_n; ++i) + sieve[i] = 255; + + /* Starting from 3 */ + for (i = 2; i * i <= N; ++i) { + offset = i % 8; + byte = (int) (i / 8); +#ifdef _DEBUG +//printf("Byte:%d[offset:%d]\n", byte, offset); + printf("Check %d[%d] - %d\n", byte, offset, check_bit(sieve[byte], offset)); +#endif + if (check_bit(sieve[byte], offset)) { + num = i + (i - 1); + for (j = num + 2 * num; j < n; j += 2 * num) { +#ifdef _DEBUG + printf("i[%d], j[%d]. step: %d\n", i, j, 2 * num); +#endif + in_offset = (int)((j + 1) / 2) % 8; + in_byte = (int)((int)((j + 1) / 2) / 8); + //in_offset = (i + j) % 8; + //in_byte = (int) ((i + j) / 8); + +#ifdef _DEBUG + printf("Zeroing %d[%d]\n!=!=!\n", in_byte, in_offset); +#endif + /* 128 = 1000000 */ + sieve[in_byte] = sieve[in_byte] & ~(128 >> in_offset); + } + } + } + + + for (i = 0; i < byte_n - 1; ++i) { +#ifdef _DEBUG + printf("Counting bits at byte %d, found %d bits\n", i, count_bits(sieve[i], 7)); +#endif + res += count_bits(sieve[i], 7); + } + + offset = (N - 1) % 8; + +#ifdef _DEBUG + printf("Counting bits at byte %d, found %d bits[final]\n", i, count_bits(sieve[i], offset)); +#endif + res += count_bits(sieve[i], offset); + printf("%d", --res); +} + +int check_bit(char x, int pos) { + return (x >> (7 - pos)) & 1; +} + +int count_bits(char x, int max_offset) { + int res = 0; + for (int i = 0; i <= max_offset; ++i) { + res += check_bit(x, i); + } + return res; +}