nihonium
/
mipt_clang
Archived
1
0
Fork 0

eratosfen

remotes/private/master
nihonium 3 years ago
parent f5953dd54e
commit 89a7e5134c

@ -0,0 +1,92 @@
#include <stdio.h>
#include <stdlib.h>
#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;
}