GMP(GNU多精度数学库)是一个功能强大的开源数学库,用于高精度计算和操作任意精度的整数、有理数和浮点数。它提供了一组丰富的函数和数据类型,使得处理大数和高精度计算变得容易和高效。
以下是 GMP 库的一些主要特点和功能:
- 任意精度计算:GMP 允许处理任意精度的整数、有理数和浮点数,不受标准整数和浮点数类型的限制。通过 GMP,可以进行准确度高达数百万位的计算。
- 高效的算法:GMP 库通过使用高效的算法和数据结构来实现快速的大数计算。它使用了各种优化技术,如手动调整乘法算法、快速离散傅立叶变换(FFT)等。
- 丰富的功能:GMP 提供了一系列的数学函数和操作,包括基本的算术运算、位操作、比较运算、转换函数、随机数生成、高级数论运算(如最大公约数、质因数分解、素数测试)等。
- 灵活的数据类型:GMP 引入了自己的数据类型来表示大整数(mpz_t)、有理数(mpq_t)和浮点数(mpf_t)。这些数据类型可以动态分配和调整内存大小,以适应任意精度的计算需求。
- 跨平台支持:GMP 是一个跨平台的库,可以在各种操作系统上使用,包括 Windows、Linux、Mac 等。它使用纯 C 语言编写,因此可以与各种编程语言进行集成。
- 广泛应用:GMP 库被广泛应用于科学计算、密码学、密码分析、符号计算、编译器优化等领域。它提供了很多基础工具和函数,用于构建其他高级数学库和应用程序。
GMP 是一个功能强大且高度优化的开源数学库,用于高精度计算和操作任意精度的数值。它提供了丰富的功能和灵活的数据类型,适用于各种数学操作和应用场景。
一些常用操作、
- mpz_t:
mpz_t
是 GMP 中表示任意精度整数的数据类型。它通过动态分配的内存来存储大整数,并提供了各种函数和操作,用于进行整数的基本运算、位操作、比较运算等。 - mpq_t:
mpq_t
是 GMP 中表示任意精度有理数的数据类型。它由两个mpz_t
对象组成,一个表示分子,一个表示分母。mpq_t
类型提供了函数和操作,用于进行有理数的基本运算、转换、比较等。 - mpf_t:
mpf_t
是 GMP 中表示任意精度浮点数的数据类型。它可以用来进行高精度的浮点数计算,支持加法、减法、乘法、除法、指数、对数运算等。mpf_t
类型具有用户可选的精度,可以通过设置小数位数来控制计算精度。 - 上述类型的数据的位数都是动态扩展的!!!
mpz_t类型基本操作!!!
#include<iostream>
#include<gmp.h>
using namespace std;
int main()
{
//定义
mpz_t z1,z2,z3; //创建没有位数限制的高精度有符号整数
//默认初始化
mpz_init(z1); //初始化为0,每一个mpz_t类型数据使用前都需要初始化!
mpz_init(z2); //初始化为0,每一个mpz_t类型数据使用前都需要初始化!
mpz_init(z3); //初始化为0,每一个mpz_t类型数据使用前都需要初始化!
//数字初始化
mpz_init_set_si(z1,-100); //使用一个 signed int 有符号数来初始化,可以是负数和正数!
mpz_init_set_ui(z1,100); //使用一个 unsigned int 无符号数来初始化,只能为正数!
//mpz_t类型初始化
mpz_init_set(z2,z1); //将z1的值赋值给z2
//字符串初始化
char num[] = "114514"; //数字字符串,要保证只有数字字符!!!
mpz_init_set_str(z1,num,10); //使用一个数字字符串来初始化,需要指定进制
//使用字符串赋值
mpz_set_str(z1,"114514",10);
//使用数字赋值
mpz_set_si(z1,-100); //使用一个 signed int 有符号数来赋值,可以是负数和正数!
mpz_set_ui(z1,100); //使用一个 unsigned int 无符号数来赋值,只能为正数!
//使用mpz_t类型来赋值
mpz_set(z1,z2);
//获取字符串
char buffer[512];
mpz_get_str(buffer,10,z1); //转换为字符串类型,需要指定缓冲区(缓冲区大小要足够!)和进制;
//比较运算
mpz_cmp(z1,z2); //比较两个mpz_t类型数据的大小;z1 = z2返回0;z1 > z2 返回大于0;z1 < z2 返回小于0
mpz_cmp_si(z1,100); //将mpz_t类型数据与 signed int 类型数据比较,返回值和上述相同
//加法运算
mpz_add(z3,z1,z2); //mpz_t类型的加法,z3 = z1 + z2
mpz_add_ui(z3,z1,10); //mpz_t类型的加法,z3 = z1 + 10; 注意10是ui类型数据,unsigned int无符号整数!!!
//gmp库没有提供mpz_add_si类型的函数!!!!
//减法运算
mpz_sub(z3,z1,z2); //mpz_t类型的减法,z3 = z1 - z2;
mpz_sub_ui(z3,z1,10); //z3 = z1 - 10;
//乘法运算
mpz_mul(z3,z1,z2); //z3 = z1 * z2
mpz_mul_ui(z3,z1,10); //z3 = z1 * 10
//除法运算
mpz_div(z3,z1,z2); //z3 = z1 / z2
mpz_div_ui(z3,z1,10); //z3 = z1 / 10
//幂运算
mpz_pow_ui(z3,z1,10); //z3 = z1 ** 10
mpz_powm(z3,z1,z2,z2); //z3 = z1 ** z2 mod z2
//取余运算
mpz_mod(z3,z1,z2); //z3 = z1 mod z2
mpz_mod_ui(z3,z1,10); //z3 = z1 mod 10;
//获取质数
mpz_nextprime(z1,z1); //获取大于z1的下一个质数并赋值给z1
//验证是不是质数
mpz_probab_prime_p(z1,15); //返回值为0,1,2;当返回值为2时是素数的概率极高,接近百分白;返回值为1时给定整数可能是素数,但可能存在较小的错误概率;返回值为0时给定整数不是素数;15是测试的次数,通常使用15次的测试已经可以给出较高的准确性;
//获取随时间变化的随机数
//(1)设置默认随机状态为跟着时间改变,也就是引入时间随机数种子
gmp_randstate_t state;
gmp_randinit_default(state);
gmp_randseed_ui(state,time(NULL));
//(2)生成指定位数的随机数,例如1024位
mpz_urandomb(z1,state,1024);
//计算两个整数的最大公约数
mpz_gcd(z3,z1,z2); //计算z1和z2的最大公约数,结果保存至z3中
//计算最小公倍数,公式:最小公倍数 = (num1 * num2) / 最小公约数
mpz_set_ui(z1,18);
mpz_set_ui(z2,6);
mpz_t z4,z5;
mpz_init(z4);
mpz_init(z5);
mpz_gcd(z3,z1,z2); //z3是最小公约数
mpz_mul(z4,z1,z2); //z4 = z1 * z2;计算乘积!
mpz_div(z5,z4,z3); //z5 = z4 / z3;z5是最小公倍数!
//标准输出
gmp_printf("%Zd\n",z5);
//通过输入设置一个mpz_t类型数据的大小
char num_buffer[512];
cin >> num_buffer;
mpz_t z6;
mpz_init_set_str(z6,num_buffer,10);
//按位与运算
mpz_and(z1,z2,z3); //z1 = z2 & z3
//按位或运算
mpz_ior(z1,z2,z3); //z1 = z2 | z3
//按位异或运算
mpz_xor(z1,z2,z3); //z1 = z2 ^ z3
//按位取反操作
mpz_com(z1,z1); //z1 = ^z1
//左移位运算
mpz_mul_2exp(z1,z1,2); //z1 = z1 << 2;
//右移位运算
mpz_tdiv_q_2exp(z1,z1,2); //z1 = z1 >> 2;
//清理
mpz_clear(z1); // 清理资源
mpz_clear(z2); // 清理资源
mpz_clear(z3); // 清理资源
mpz_clear(z4); // 清理资源
mpz_clear(z5); // 清理资源
mpz_clear(z6); // 清理资源
return 0;
}
Comments NOTHING