我一直试图得到问题3的项目Euler的答案,我需要找到最大的素数因子600851475143,但我的程序挂起了这个数字,而不是更小的(或有时更大的)。我删除了程序的更一般的目的,找到素数因子化,希望它会减少计算时间,也许给我一个答案,但事实并非如此。之前,当程序从1开始而不是输入时,它给了我最低的素数,17,但仅此而已。现在它什么也没给我。
对于其他人来说,似乎有用的是增加数据类型的大小并附加“ULL'到变量的末尾。这对我没有用。其他人建议创建一个大型的课程,但我还不够知识,或者根本不能与课程一起工作。这是程序。
#include <iostream>
using namespace std;
bool is_prime(unsigned long long int input);
void factor_number(unsigned long long int input);
int main()
{
unsigned long long int input = 600851475143ULL;
cout << "Hello World!\n\n";
if (is_prime(input) == false)
factor_number(input);
else
cout << input << 1;
cin.get();
return 0;
}
bool is_prime(unsigned long long int input)
{
for (int i = 1; i <= input; i++)
{
if (i != 1 && i != input)
{
if (input % i == 0)
{
return false;
}
}
else if (i == input)
return true;
}
}
void factor_number(unsigned long long int input)
{
unsigned long long int i = input;
while (input % i != 0 || is_prime(i) == false)
{
i--;
}
cout << i << endl;
}
答案 0 :(得分:6)
bool is_prime(unsigned long long int input)
{
for (int i = 1; i <= input; i++)
unsigned long long int
input
可以存储值[0,2 ^ 64]。
int
i
可以存储[ - (2 ^ 31),2 ^ 31)之间的值。
当i
为2,147,483,647
并且您将其递增时,它会变为负值,因此当i <= input
为&gt; = 2 ^时,循环条件input
永远不会为假31。如果i
为unsigned int
,则值>&2; = 32时会出现问题。
#include <iostream>
#include <cstdint>
#include <limits>
int main() {
int i = std::numeric_limits<int>::max();
std::cout << i << "\n";
++i;
std::cout << i << "\n";
}
当你比较i
和input
时,你的编译器会给你一个警告,但是你选择忽略它。
您可以通过以下方式修复代码:
#include <cstdint>
bool is_prime(uint64_t input)
{
for (uint64t_t i = 1; i <= input; ++i) {
---编辑---
你的主要功能也是这样:
for (int i = 1; i <= input; i++)
{
if (i != 1 && i != input)
{
循环内的测试条件可能很昂贵(在这种情况下,您可以对循环的每次迭代进行测试)。如果您担心代码的性能,首先应该尝试消除这些测试。
循环包含i != input
的测试 - 所以让我们将其提升到循环条件:
for (uint64_t i = 1; i < input; i++)
{
...
}
return true;
现在我们不需要在循环内测试i != input
,但我们仍然需要测试那个讨厌的1。我们可以在开始时添加一些明确的测试:
if (input < 4) {
return (input > 1); // 2 and 3 are prime, 0 and 1 are not
}
但更重要的是,我们可以快速消除所有偶数。如果数字的最低位是&#39; 0&#39;然后数字是均匀的:
if ((input & 1) == 0) // even number
return false;
但现在我们知道这个数字不算均匀,我们也可以做更少的分组测试。把它们放在一起:
#include <iostream>
bool is_prime(uint64_t input)
{
if (input < 4)
{
// eliminate 1, 2 and 3.
return (input > 1);
}
// Eliminate even numbers
if ((input & 1) == 0)
return false;
// we've eliminated even numbers, so the smallest
// possible divisor is 3, start from there, but
// we can also skip all even divisors!
for (uint64_t div = 3; div <= input / 3; div += 2)
{
if ((input % div) == 0)
return false;
}
return true;
}
int main()
{
for (uint64_t i = 0; i < 64; ++i)
{
std::cout << i << ": " << (is_prime(i) ? "yes" : "no") << '\n';
}
}