- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
想必大家都遇到过埃拉托色尼筛按位运算的优化代码吧。我正在努力解决这个问题,但我对这个实现中的一个操作有疑问。这是来自 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]
为什么我们除以 64
而不是 32
,当我们使用 32 位整数时;int prime[n/64]
如果 n < 64
正确?最佳答案
代码中存在多个问题:
makeComposite()
应该有返回类型 void
.(1 << ((x >> 1) & 31))
有未定义的行为如果 x == 63
因为1 << 31
溢出类型 int
的范围.你应该使用 1U
或者最好是 1UL
以确保 32 位。return (prime[x / 64] >> ((x >> 1) & 31)) & 1;
int
有 32 位,你应该使用 uint32_t
作为位数组的类型。int prime[n / 64];
如果 n
太短不是 64 的倍数。使用 uint32_t prime[n / 64 + 1];
反而。这对您的示例来说是一个问题 n = 30
, 所以创建的数组长度为 0
.ifnotPrime(n)
仅返回奇数的有效结果。更改此函数并将其命名为 isOddPrime()
可能会更好且更具可读性.关于您的问题:
what is the meaning of
(prime[x/64] & (1 << ((x >> 1) & 31))
and more specifically(1 << ((x >> 1) & 31))
?
x
先除以 2(右移一位),因为只有奇数在数组中有位,然后结果用 31 掩码以保留低 5 位作为字中的位号。对于任何无符号值 x
, x & 31
相当于x % 32
. x / 64
是测试该位的字号。
如上所述,1
是一个 int
因此不应向左移动 31 个位置。使用 1UL
确保该类型至少有 32 位,并且可以移动 31 个位置。
in
prime[x/64]
why do we divide by64
and not with32
, when we work with 32-bit integer?
数组中的位对应奇数,所以一个 32 位的字包含 64 个数的素数信息:32 个已知为合数的偶数和 32 个奇数,如果该数为合成的。
Is
int prime[n/64]
correct ifn < 64
?
不是不是,如果n
是不正确的不是 64
的倍数: 大小表达式应为 (n + 63) / 64
, 或更好 int prime[n/64 + 1]
这是修改后的版本,您可以在其中传递命令行参数:
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
bool isOddPrime(const uint32_t prime[], unsigned 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 1 ^ ((prime[x / 64] >> ((x >> 1) & 31)) & 1);
}
// Marks x composite in prime[]
void makeComposite(uint32_t prime[], unsigned 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] |= (1UL << ((x >> 1) & 31));
}
// Prints all prime numbers smaller than n.
void bitWiseSieve(unsigned n) {
// Assuming that n takes 32 bits, we reduce
// size to n/64 from n/2.
uint32_t prime[n / 64 + 1];
// 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 (unsigned i = 3; i * i <= n; i += 2) {
// If i is prime, mark all its multiples as composite
if (isOddPrime(prime, i)) {
for (unsigned j = i * i, k = i << 1; j < n; j += k)
makeComposite(prime, j);
}
}
// writing 2 separately
if (n >= 2)
printf("2\n");
// Printing other primes
for (unsigned i = 3; i <= n; i += 2) {
if (isOddPrime(prime, i))
printf("%u\n", i);
}
}
// Driver code
int main(int argc, char *argv[]) {
unsigned n = argc > 1 ? strtol(argv[1], NULL, 0) : 1000;
bitWiseSieve(n);
return 0;
}
关于c - Eratosthenes 筛法 - 按位优化问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61931217/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!