加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

GMP大数库VC使用入门教程

发布时间:2020-12-14 04:09:25 所属栏目:大数据 来源:网络整理
导读:Winxos 2009-9-29 GMP是GUN的一套大数库,提供了数百个基础函数,执行效率比较高,但是网上相对来说详细的教程比较少,本教程为大家介绍如何在windows?,vc6.0开发环境下,配置和使用GMP库。 附件下载地址: http://d.namipan.com/sd/929339 ? 附件包括gmp编

Winxos 2009-9-29

GMP是GUN的一套大数库,提供了数百个基础函数,执行效率比较高,但是网上相对来说详细的教程比较少,本教程为大家介绍如何在windows?,vc6.0开发环境下,配置和使用GMP库。

附件下载地址:http://d.namipan.com/sd/929339?

附件包括gmp编译好的静态库文件gmp.h gmp.lib 以及一份word文档和gmp函数手册

一、?编译GMP库

直接从GMP主页上下载到的GMP源代码,在windows环境下编译起来相对比较麻烦,所以我还是推荐大家直接使用我已经编译好的库,附件中已经包含。

(使用我编译好的库与你们自己编译的库就是一些参数不同,可能效率有点不一样,但是我们不用管这些细微的差异,主要是看看如何使用GMP库吧)

二、?配置库

编译好的库文件包含gmp.h,gmp.lib两个文件,为了以后编程的方便,建议将这两个文件放到VC系统库目录,这样以后编程的时候就可以具体调用了。

具体的做法:

将gmp.h文件放置到VC头文件目录中,在我电脑中对应的目录为

E:Program FilesMicrosoft Visual StudioVC98Include

将gmp.lib文件放置到VC库文件目录中,在我电脑中对应的目录为

E:Program FilesMicrosoft Visual StudioVC98Lib

注:如果你的VC装在不同的目录,找到对应的地方就可以了

好了,万事具备了,可以开始编写程序了

三、?编写程序

打开VC6.0,新建一个WIN32 CONSOLE工程(默认的HELLO WORLD 就可以),对工程进行如下设置:

选择?工程?->?设置?,如下图

弹出的对话框进行如下图设置,目的是为了添加gmp.lib库文件到工程。

好了,确定完后就可以代码编写了。

在主程序文件输入以下代码:

/*GMP简单教程winxos 2009-9-29*/
#include "stdafx.h" //hello world 工程默认的,如果你建立的是空工程就不需要这句
#include <gmp.h> //记得引入GMP.H的头文件
int main(int argc,char* argv[])
{
    mpz_t t; //mpz_t 为GMP内置大数类型	
    mpz_init(t); //大数t使用前要进行初始化,以便动态分配空间	
    mpz_ui_pow_ui(t,2,100); //GMP所有函数基本都是以mpz打头 	
    gmp_printf("2^100=%Zdn",t); //输出大数,大数的格式化标志为%Zd 	
    mpz_clear(t);	
    return 0;
}

 

编译,运行结果如下:

是不是比较简单呢?相信您一定跃跃欲试了吧^_^

四、?高级教程

对于刚开始使用GMP库来说,就是不知道有哪些函数,容易被它繁多的函数吓到,到官方主页上去,就可以找到最新的帮助文档,英文的。

实际上可以发现它的众多函数命名是比较有规律的,而且对于大数运算来说常用的函数并不多。附件中包含了常用整数函数手册。

GMP的函数命名通常为

mpz_funxx_dataxx

其中funxx表示函数功能,dataxx表示数据类型,dataxx省略通常表示数据都是大数

举例如下:

mpz_t t;//这是类型声明,都需要的东西?
mpz_init(t);//普通初始化,还有别的初始化方式,比如赋值初始化?
mpz_set_ui(t,2);//赋值操作,ui表示无符号32位整数 //上面两句等同于mpz_init_set_ui(t,2);?
mpz_set_str(t,”1234”);//从字符串赋值,跟上面是不用的赋值类型,str表示字符串?
mpz_add(t,a,b);//将大数a+b的结果赋值给t,就是t=a+b?
mpz_add_ui(t,uib);//将小数uib与大数a求和结果赋值给t,就是t=a+uib?
//就是t=t+1?
mpz_sub(t,0)">//减法?
mpz_mul(t,0)">//乘法?
gmp_printf(“%Zd”,t);//输出t 

?

其他的类似,请参考手册。

注:如果要熟练还是要多多的练习,应该涉及大数的问题应该不是什么问题了,不过好的算法才是王道。本篇文章意在给那些想处理大数确不知如何使用GMP库的人,winxos自己也是初学者,如果有什么错误恳请指出,一起学习。

再附上一些完整的使用GMP的C++代码。
程序一、
//梅森素数的鲁卡斯测试以及概率测试
#include <iostream>
#include <gmp>
#include <PRIMES.h> //包含了我自己定义的素数相关类,本程序调用了其产生小素数
#include <ctime>
using namespace std;
#pragma comment(lib,"gmp.lib"); //另外一种引用库的方法
int IsMersenne(int ExpP)
{	
	if (ExpP == 2)
		return 1;	
	mpz_t c,b;	
	mpz_init(c);	
	mpz_init(b);	
	mpz_ui_pow_ui(c,ExpP); 	
	mpz_sub_ui(c,c,1);			//M(p) = 2^p-1	
	mpz_set_ui(b,4);	
	for (int j = 0;j < ExpP-2;j++)	
	{		
		mpz_mul(b,b,b);	
		mpz_sub_ui(b,2);		
		mpz_mod(b,c);	
	}
	mpz_clear(c);
	if (mpz_cmp_ui(b,0) == 0)	
	{	
		mpz_clear(b);	
		return 1;	
	}	
	mpz_clear(b);	
	return 0;
}

int IsMersenne2(int ExpP)
{	
	if (ExpP == 2) 
	    return 1;	
	mpz_t c;	
	mpz_init(c);	
	mpz_ui_pow_ui(c,ExpP);
	mpz_sub_ui(c,1);	
	if (mpz_probab_prime_p(c,5))
	{		
		return 1;	
	}	
	return 0;
}

int main()
{	
	time_t a,b;	
	PRIMES P;	
    int i,ct = 0;	
	a=time(0);	
	for (i = 900;i < 1100;i++)
	{	
		int ExpP = P.PrimeAt(i);	
		SetTitle(ExpP);		
		if (IsMersenne2(ExpP))		
		{		
			cout<<++ct<<"t"<<ExpP<<endl;	
		}	
	}
	b=time(0);	
	cout<<difftime(b,a)<<"秒"<<endl;	
	return 0;
}
		


程序二、
//Euler project 第二十题
int e20()
{	
	mpz_t n;	
	int i,sum=0;
	mpz_init_set_ui(n,1);	
	for (i=2;i<=100;i++)	
	{		
		mpz_mul_ui(n,n,i);
	}
	gmp_printf("%Zdn",n);	
	while (mpz_cmp_ui(n,0)>0)	
	{		
		sum+=mpz_fdiv_ui(n,10);	
		mpz_div_ui(n,10);
	}
	printf("%dn",sum);
	mpz_clear(n);	
	return 0;
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读