#include <stdio.h>
main()
{
long n=600851475143;
int i,j,flag;
for(i=2;i<=n/2;i++)
{
flag=1;
if(n%i==0)//finds factors backwards
{
for(j=2;j<=(n/i)/2;j++)//checks if factor is prime
{
if((n/i)%j==0)
flag=0;
}
if(flag==1)
{
printf("%d\n",n/i);//displays largest prime factor and exits
exit(0);
}
}
}
}
上面的代码适用于n = 6008514751
,但是,它不适用于n = 600851475143
,即使该数字仍然在long
的范围内。
我该怎么做才能让它发挥作用?
6条答案
按热度按时间bjg7j2ky1#
一个潜在的问题是
i
和j
是int
,并且对于大的n
可能溢出(假设int
比long
窄,这是经常发生的)。另一个问题是,对于n= 600,851,475,143,你的程序做了相当多的工作(最大的因子是6857),期望它花很长时间来完成是合理的。
rsl1atfo2#
使用
long
s代替int
s。更好的是,使用自C99以来定义的uint64_t
(确认Zaibis)。它在所有平台上都是64位无符号整型。(您所拥有的代码在某些平台上会溢出)。现在我们需要让您的算法更快地工作:
你的质数测试效率很低你不需要遍历所有的偶数,只需要遍历素数最大等于您正在测试的数字的平方根(而不是您当前所做的一半)。
你从哪里得到质数呢?好吧,递归调用你的函数。尽管实际上我很想缓存质数,比如说,65536。
ghhaqwfi3#
来自ISO/IEC 9899:TC 3
5.2.4.2.1整型的大小
[...]
它们的实现定义值的大小(绝对值)应等于或大于所示值,符号相同。
[...]
最小长度-2147483647 // -(2^31 - 1)
最大长度+2147483647 // 2^31 - 1
编辑:
抱歉,我忘了加上这应该告诉你什么。
点是长的甚至不需要能够容纳你提到的值,因为标准规定它必须能够容纳至少4个带符号的字节,所以有可能你的机器只能在
long
类型的变量中容纳最多2147483647的值。5vf7fwbs4#
在32位计算机上,
long
的范围为-2,147,483,648
到2,147,483,647
;在64位计算机上,其范围为-9,223,372,036,854,775,808
到9,223,372,036,854,775,807
(注:这不是C标准强制要求的,并且可能因编译器而异)。正如OP在评论中所说,他是32位的,
600851475143
超出了范围,因为它不适合long
的范围。ct3nt3jp5#
尝试将
n
更改为long long int
..并将i,j更改为longEDIT:定义n如下:
LL
-是强制long long类型的后缀...yws3nbqq6#
这是我的解决方案: