大数如何求余?

jeff_nie 2010-10-17 06:59:14
在Project Euler做题,才到第三题就卡住,题目是求600851475143的最大质因数
原本我想用600851475143去求余sqrt(600851475143),但600851475143这个数只能用double数据类型来存储,而浮点类型又不能做求余运算,请问像600851475143这样的大数如何求余呢?还是这道题我的思路不对,谢谢。
...全文
918 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
tagMsg 2011-05-21
  • 打赏
  • 举报
回复
LZ可以参考Linux源码中IPSEC部分有一个计算大数取余的第三方包。
AnYidan 2011-05-20
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 baihacker 的回复:]
C/C++ code

typedef long long int64;
int64 n = 60081475143LL;
for (int64 i = 2; ; ++i)
{
if (i * i > n) break;
while (n % i == 0) n /= i, @1;
}
if (n != 1) @2;

@1中的i和@2中的n较大的为所求。
[/Quote]

@1 和@2 是神马?
wenhaoz 2011-05-20
  • 打赏
  • 举报
回复
这贴沉了。。。我顶一下。。。。
乐CC 2010-10-20
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 baihacker 的回复:]
C/C++ code

typedef long long int64;
int64 n = 60081475143LL;
for (int64 i = 2; ; ++i)
{
if (i * i > n) break;
while (n % i == 0) n /= i, @1;
}
if (n != 1) @2;

@1中的i和@2中的n较大的为所求。
[/Quote]
这个意思是不断除自己的因数,直到sprt(n),也就是i*i>n跳出,i会记录从2到sqrt(n)中最大的因数,当然,如果最后还剩一个没法除,那他本身也是质数,所以取@1和@2中的大者
liutengfeigo 2010-10-20
  • 打赏
  • 举报
回复
飞雪的代码很神奇。
jeff_nie 2010-10-20
  • 打赏
  • 举报
回复
应该不是数据范围的问题,long long取值范围在:-9223372036854775808 ~ 9223372036854775807之间,远大于 600851475143,关键是算法问题,运行时间太长了,所以结果一直出不来:(
jeff_nie 2010-10-20
  • 打赏
  • 举报
回复
@飞雪,你的意思我还是没太明白
@忘忧草,我的思路是和你差不多,只是我没用到数组存储,直接用了分支和循环,代码如下:

#include <stdio.h>
#include <math.h>

typedef long long int64;

int main()
{
int64 n = 600851475143LL;

int64 i;

for (i = n; i >= 2; i--)
{
int flag = 1;
if (n % i == 0) // 如果i是n的因数
{
int j;
for (j = 2; j <= sqrt(i); j++)
if (i % j == 0) // 判断是否不是质数
flag = 0;


if (flag == 1) // 如果是质数
{
printf("%d", i);
break;
}
}
}

return 0;
}



但是,我的问题还是在数据类型上,long long 数据类型还是存储不了600851475143LL 这个数,如果将n的值设置小些,上面的代码是能正确输出n的最大质因数的。
baihacker 2010-10-20
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 jeff_nie 的回复:]
引用 6 楼 void_wuyu 的回复:
引用 1 楼 baihacker 的回复:
C/C++ code

typedef long long int64;
int64 n = 60081475143LL;
for (int64 i = 2; ; ++i)
{
if (i * i > n) break;
while (n % i == 0) n /= i, @1;
}
i……
[/Quote]
你再仔细看看。
jeff_nie 2010-10-20
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 void_wuyu 的回复:]
引用 1 楼 baihacker 的回复:
C/C++ code

typedef long long int64;
int64 n = 60081475143LL;
for (int64 i = 2; ; ++i)
{
if (i * i > n) break;
while (n % i == 0) n /= i, @1;
}
if (n != 1) @2;

@1中的i……
[/Quote]

这个办法我也想过,那会不会存在大于sqrt(n)的质因数呢?因为你的运算范围是在sqrt(n)之内的。
因为,我想先找最大的素数,再判断是不是因数。这样,可以减少运行次数。
jeff_nie 2010-10-20
  • 打赏
  • 举报
回复
600851475143 这个数是千亿了,用硬办法去先找因数,再判断质数的方法,10亿内还能接受,几十秒,到百亿估计是出不来了。有没有好点的算法呢?
zhangxun2007 2010-10-17
  • 打赏
  • 举报
回复
1,求出不超过sqrt(600851475143)的所有质数;
方法:
int a;
a=(int)(sqrt(600851475143));//强制转换
使用循环,做辗转相除,将所得质数用数组按从大到小顺序储存。
2,用数组中最大数除600851475143,
若能整除,即为所求,停止;若不能,用次最大除600851475143,重复这个过程,直到最后结束。
baihacker 2010-10-17
  • 打赏
  • 举报
回复

typedef long long int64;
int64 n = 60081475143LL;
for (int64 i = 2; ; ++i)
{
if (i * i > n) break;
while (n % i == 0) n /= i, @1;
}
if (n != 1) @2;

@1中的i和@2中的n较大的为所求。

69,370

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧