利用gmp库查找完美数 ...

完美数的定义:若一个数能写成其所有因数之和,则称之为完美数。
如: 6 = 1 + 2 + 3 = 2 * 3
  28 = 1 + 2 + 4 + 7 + 14 = 4 * 7
 这些完美数都满足为两个数的乘积构成,且第二个数为质数
 公式:  (2^(n-1)) * (2^n -1)
 即,现在我们只需从2的n次幂开始找,只要2^n - 1 为质数,就可以确定一个完美数了。一般的质数判别(试除法)虽然100%正确,但如果数字太大,则太太太慢了。所以下面介绍一种更快的判断方法。
 
通过利用gmp库中的Miller-Rabin函数来快速判断质数
关于GMP库的更多信息请点击下面链接

Linux gmp类库的简单使用(一)

代码:

#include <iostream>
#include "gmpxx.h"
#include <time.h>
#include <stdio.h>
using namespace std;
int main()
{

    mpz_t num;
    mpz_t n;
    mpz_init_set_str(num,"0",10);
    mpz_init_set_str(n,"0",10);
    long expo;
    int m;
    int flag;
    for(;;)
    {
        cin>>m;
        expo = 2;
        for(int i = 0;i < m;expo ++)
        {
            mpz_ui_pow_ui(num,2,expo);
            mpz_sub_ui(num,num,1);
            flag = mpz_probab_prime_p(num,30);
            if(flag == 1 || flag == 2)
            {
                time_t tt = time(NULL);//这句返回的只是一个时间cuo
                tm* t= localtime(&tt);
                printf("\n第%d个完美数:  %02d%02d%02d:%02d:%02d\n",
                       i+1,
                       t->tm_mon,
                       t->tm_mday,
                       t->tm_hour,
                       t->tm_min,
                       t->tm_sec
                       );
                cout<<"expo = "<<expo<<endl;
                mpz_ui_pow_ui(n,2,expo-1);
                gmp_printf("%Zd * ",n);
                gmp_printf("%Zd = ",num);
                mpz_mul(num,num,n);
                gmp_printf("%Zd\n\n",num);
                i++;
            }
        }

    }
    return 0;
}

运行结果:

第1个完美数:  11月20日  17:28:51
expo = 2
2 * 3 = 6
第2个完美数:  11月20日  17:28:51
expo = 3
4 * 7 = 28
第3个完美数:  11月20日  17:28:51
expo = 5
16 * 31 = 496
第4个完美数:  11月20日  17:28:51
expo = 7
64 * 127 = 8128
第5个完美数:  11月20日  17:28:51
expo = 13
4096 * 8191 = 33550336
第6个完美数:  11月20日  17:28:53
expo = 17
65536 * 131071 = 8589869056
第7个完美数:  11月20日  17:28:53
expo = 19
262144 * 524287 = 137438691328
第8个完美数:  11月20日  17:28:53
expo = 31
1073741824 * 2147483647 = 2305843008139952128
第9个完美数:  11月20日  17:28:53
expo = 61
1152921504606846976 * 2305843009213693951 = 2658455991569831744654692615953842176
第10个完美数:  11月20日  17:28:53
expo = 89
309485009821345068724781056 * 618970019642690137449562111 = 191561942608236107294793378084303638130997321548169216

转载于:https://www.cnblogs.com/tolic/p/7142247.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值