我正在尝试找到数字600851475143的最大素数因子 . 我的代码适用于我测试的较小数字(低于100) . 但是当面对600851475143时,它返回4370432,绝对不是素数 . 任何想法我的代码可能有什么问题?
#include <iostream>
#include <time.h>
#include <math.h>
using namespace std;
int main()
{
int num;
int largest;
int count;
cout<<"Please enter a number to have its Largest Prime Factor found"<<endl;
cin>>num;
num = 600851475143;
for (int factor = 1; factor <= num; factor++)
{
if (num % factor == 0)
{
count = 0;
for (int primetest=2; count == 0 && factor > primetest ; primetest++)
{
if (factor % primetest == 0)
count ++;
//endif
}
if (count == 0)
largest = factor;
//endif
}
}//endif
cout<<largest<<endl;
system("PAUSE");
}
4 回答
这里发生整数溢出 .
num
的大小不足以包含您提供的值 .使用
uint64_t
.阅读本文:cstdint
代码有很多主要问题,所以我想展示一个更好的完整解决方案 . 主要问题是它没有输入验证!好的代码必须在它不拒绝的所有输入上都是正确的 . 所以我现在已经包含了适当的阅读和输入验证 . 通过这种方式,您可以自动发现问题 .
所有主要类型都需要有专有名称!所以我介绍了typedef uint_type . 如果输入60085147514有效,编译器也会在编译时发现(尽管现在也在运行时被拒绝) . 如果编译器发出警告,那么你需要使用更大的整数类型;但是,在所有常见的64位平台上,无符号长度就足够了(但在普通的32位平台上却没有) . 如果您需要更大的整数类型,那么现在只需要更改一个地方 .
你的算法非常低效!所需要的只是将数字除以找到的所有因子(尽可能长),并且保证只能遇到素数 - 所以不需要检查它 . 并且还需要考虑直到输入的平方根的因子 . 这一切都需要一些逻辑思考 - 参见代码 .
然后你的代码违反了局部性原则:将变量声明在需要的地方,而不是其他地方 . 您还包括非C标头,此外不需要 . use-directives的使用只会混淆代码:你不再看到组件的来源;而且没有必要!我还介绍了一个匿名命名空间,用于更突出的定义 .
最后,我使用更紧凑的编码风格(2个空格缩进,同一行上的括号,尽可能避免使用括号 . 想一想:通过这种方式,您可以一目了然地看到更多,同时进行一些培训也更容易阅读 .
当如图所示编译时,编译器警告可能使用undefined的largest_factor . 事实并非如此,我选择将此警告视为空白 .
并提供更正 . 根据您的编译器,您可以尝试unsigned long,看看是否可以保留您的答案 . 尝试并写入cout,看看变量是否包含您期望的值 .
另一方面,如果你试图找到最大因素,那么从最高可能因素倒数就不是更有效率吗?
您可以将num变量声明为long long int .
这样可以避免代码中出现所有类型的溢出!