【发布时间】:2020-05-21 09:20:00
【问题描述】:
我想你们每个人都遇到过 Eratosthenes sieve 的按位运算优化代码。我试图绕开它,我对这个实现中的一个操作有疑问。以下是 GeeksforGeeks 的代码:
bool ifnotPrime(int prime[], int x) {
// checking whether the value of element
// is set or not. Using prime[x/64], we find
// the slot in prime array. To find the bit
// number, we divide x by 2 and take its mod
// with 32.
return (prime[x / 64] & (1 << ((x >> 1) & 31)));
}
// Marks x composite in prime[]
bool makeComposite(int prime[], int x) {
// Set a bit corresponding to given element.
// Using prime[x/64], we find the slot in prime
// array. To find the bit number, we divide x
// by 2 and take its mod with 32.
prime[x / 64] |= (1 << ((x >> 1) & 31));
}
// Prints all prime numbers smaller than n.
void bitWiseSieve(int n) {
// Assuming that n takes 32 bits, we reduce
// size to n/64 from n/2.
int prime[n / 64];
// Initializing values to 0 .
memset(prime, 0, sizeof(prime));
// 2 is the only even prime so we can ignore that
// loop starts from 3 as we have used in sieve of
// Eratosthenes .
for (int i = 3; i * i <= n; i += 2) {
// If i is prime, mark all its multiples as
// composite
if (!ifnotPrime(prime, i))
for (int j = i * i, k = i << 1; j < n; j += k)
makeComposite(prime, j);
}
// writing 2 separately
printf("2 ");
// Printing other primes
for (int i = 3; i <= n; i += 2)
if (!ifnotPrime(prime, i))
printf("%d ", i);
}
// Driver code
int main() {
int n = 30;
bitWiseSieve(n);
return 0;
}
所以我的问题是:
-
(prime[x/64] & (1 << ((x >> 1) & 31))更具体地说是(1 << ((x >> 1) & 31));是什么意思 - 在
prime[x/64]中,当我们使用 32 位整数时,为什么要除以64而不是32; - 如果
n < 64,int prime[n/64]是否正确?
【问题讨论】:
-
大概是因为筛子只代表奇数,不会在偶数上浪费空间。您可以轻松处理偶数。因此,您可以在 32 位中表示 64 个数字的范围。
-
OT:
bool makeComposite(...){...}-->void makeComposite(...){...} -
这段代码可读性不强,看看this,它是C++,它被写成更具可读性。基本上算法是相同的,但信息不存储在位中(没有意义的情况下 constexpr)。将
std::array更改为std:vector,您就有了版本,其中标志存储在单个位中。 -
关于问题 3:只有当 n 是 64 的倍数时它才是正确的(在 C 中,而不是在 C++ 中)。Geeksforgeeks 以不是特别好或不可靠而闻名。远离它可能是个好主意。
-
@molbdnilo 角落案例:
int prime[n/64];在 C 中当n==0或小于 0 时无效,即使它是 64 的倍数。
标签: c bit-manipulation bitwise-operators bit-shift sieve-of-eratosthenes