GMP多精度运算库

官网

http://gmplib.org/

安装

sudo yum install lzip

tar xvf gmp-6.2.1.tar.lz --lzip

cd gmp-6.2.1

./configure 

make

make install

简单使用

头文件

#include <gmp.h>

动态库

gcc hello.c -lgmp

数据类型

数据类型 声明
多精度整数 mpz_t
有理数、多精度分数 mpq_t
浮点数 mpf_t
多精度数的位计数 mp_bitcnt_t

变量约定

GMP函数一般先写输出变量后写输入变量,这个概念类似于赋值运算符。

BSD MP 兼容函数是特例,它们都是后写输出的。

GMP允许我们在一次调用中使用相同的输入和输出变量。
例如作整数乘法的主函数 mpz_mul,可以计算x的平方,然后把输出放回到x中,mpz_mul(x, x, x);

在对一个GMP变量赋值之前,需要通过调用一个特定的初始化函数对亡进行初始化,当用完了一个GMP变量时,需要把它清除掉,你要调用一个实现这个目的的特定函数,具
体用哪一个函数依赖于变量的类型,细节见于关于整数函数、有理数函数和实数函数的章节

一个变量只能初始化一次,或者在下一次初始化之前对它进行清除。当一个变量初始化了以后,它可以被赋值任意多的次数。

为了实现更高的效率,应该尽量减少初始化和清除。通常在函数开始时进行初始化而在其结束时进行清除。

void foo (void)
{
  mpz_t  n;
  int    i;
  mpz_init (n);
  for (i = 1; i < 100; i++)
    {
      mpz_mul (n, …);
      mpz_fdiv_q (n, …);
      …
    }
  mpz_clear (n);
}

函数类

GMP库中有六类函数

1.名字以mpz_开头的有符号整数算术函数,相关的数据类型是mpzt,这一类中有大约150个函数。

2.名字以mpq_开头的有理数算术函数,相关的数据类型是mpq_t,这一类中有大约40个函数,但是整数函数可以分别应用于对分子和分母的算术。

3.名字以mpf开头的有符号整数算术函数,相关的数据类型是mpft,这一类屮有大约60个函数。

4.与 Berkeley MP相兼容的函数,例如iom、madd和mu1t,相关的数据类犁是MINT

5.作用于自然数的快速低级函数,它们被用于前述的各类函数,对于时间要求极高的用户编程,也可以直接调用它们。这些函数以mpn_开头,相关的数据类型是mp1imb_t,这一类中有大约30个函数(用起来有难度)

6.杂类函数,包括建立用户内存分配的函数和生成随机数的函数。

参数约定

void
foo (mpz_t result, const mpz_t param, unsigned long n)
{
  unsigned long  i;
  mpz_mul_ui (result, param, n);
  for (i = 1; i < n; i++)
    mpz_add_ui (result, result, i*7);
}

int
main (void)
{
  mpz_t  r, n;
  mpz_init (r);
  mpz_init_set_str (n, "123456", 0);
  foo (r, n, 20L);
  gmp_printf ("%Zd\n", r);
  return 0;
}

整数模块

整数初始化

mpz_init(a);

整数赋值

Function: void mpz_set (mpz_t rop, const mpz_t op)
Function: void mpz_set_ui (mpz_t rop, unsigned long int op)
Function: void mpz_set_si (mpz_t rop, signed long int op)
Function: void mpz_set_d (mpz_t rop, double op)
Function: void mpz_set_q (mpz_t rop, const mpq_t op)
Function: void mpz_set_f (mpz_t rop, const mpf_t op)
Function: int mpz_set_str (mpz_t rop, const char *str, int base) //base 进制
Function: void mpz_swap (mpz_t rop1, mpz_t rop2)

组合初始化和分配功能

Function:void mpz_init_set(mpz_trop, const mpz_top)
Function:void mpz_init_set_ui(mpz_trop, unsigned long intop)
Function:void mpz_init_set_si(mpz_trop, signed long intop)
Function:void mpz_init_set_d(mpz_trop, doubleop)
int mpz_init_set_str(mpz_trop, const char *str, int base)

{
  mpz_t pie;
  mpz_init_set_str (pie, "3141592653589793238462643383279502884", 10);
  …
  mpz_sub (pie, …);
  …
  mpz_clear (pie);
}

基本算数运算

Function:void mpz_add(mpz_t rop, const mpz_t op1, const mpz_t op2)
Function:void mpz_add_ui(mpz_t rop, const mpz_t op1, unsigned long int op2)
Set rop to op1+op2.

Function:void mpz_sub(mpz_t rop, const mpz_t op1, const mpz_t op2)
Function:void mpz_sub_ui(mpz_t rop, const mpz_t op1, unsigned long int op2)
Function:void mpz_ui_sub(mpz_t rop, unsigned long int op1, const mpz_t op2)
Set rop to op1-op2.

Function:void mpz_mul(mpz_t rop, const mpz_t op1, const mpz_t op2)
Function:void mpz_mul_si(mpz_t rop, const mpz_t op1, long int op2)
Function:void mpz_mul_ui(mpz_t rop, const mpz_t op1, unsigned long int op2)
Set rop to op1 times op2.

Function:void mpz_addmul(mpz_t rop, const mpz_t op1, const mpz_t op2)
Function:void mpz_addmul_ui(mpz_t rop, const mpz_t op1, unsigned long int op2)
Set rop to rop + op1 times op2.

Function:voidmpz_submul(mpz_t rop, const mpz_t op1, const mpz_t op2)
Function:voidmpz_submul_ui(mpz_trop, const mpz_top1, unsigned long intop2)
Set rop to rop - op1 times op2.

Function:void mpz_mul_2exp(mpz_t rop, const mpz_t op1, mp_bitcnt_t op2)
Set rop to op1 times 2 raised toop2. This operation can also be defined as a left shift byop2bits.

Function:void mpz_neg(mpz_t rop, const mpz_t op)
Set rop to -op.

Function:void mpz_abs(mpz_t rop, const mpz_t op)
Set rop to the absolute value of op.

指数运算

//应该是指数运算后取模
Function:void mpz_powm(mpz_t rop, const mpz_t base, const mpz_t exp, const mpz_t mod)
Function:void mpz_powm_ui(mpz_t rop, const mpz_t base, unsigned long int exp, const mpz_t mod)
Set rop to(base raised to exp) modulo mod.

Negativeexpis supported if the inversebase-1modmodexists (seempz_invertinNumber Theoretic Functions). If an inverse doesn’t exist then a divideby zero is raised.

Function:void mpz_powm_sec(mpz_t rop, const mpz_t base, const mpz_t exp, const mpz_tmod)
Setropto(baseraised toexp)modulomod.

It is required thatexp> 0and thatmodis odd.

This function is designed to take the same time and have the same cache accesspatterns for any two same-size arguments, assuming that function arguments areplaced at the same position and that the machine state is identical uponfunction entry. This function is intended for cryptographic purposes, whereresilience to side-channel attacks is desired.

//这个应该是最朴实的指数运算
Function:void mpz_pow_ui(mpz_t rop, const mpz_t base, unsigned long int exp)
Function:void mpz_ui_pow_ui(mpz_t rop, unsigned long int base, unsigned long int exp)
Setroptobaseraised toexp. The case0^0yields 1.

输出模块

gmp_printf and friends accept format strings similar to the standard C printf

% [flags] [width] [.[precision]] [type] conv

mpz_t z;
gmp_printf ("%s is an mpz %Zd\n", "here", z);

mpq_t q;
gmp_printf ("a hex rational: %#40Qx\n", q);

mpf_t f;
int n;
gmp_printf ("fixed point mpf %.*Ff with %d digits\n", n, f, n);

mp_limb_t l;
gmp_printf ("limb %Mu\n", l);

const mp_limb_t *ptr;
mp_size_t size;
gmp_printf ("limb array %Nx\n", ptr, size);

课堂测试

exp.c

include <gmp.h>

int main(){
//init
mpz_t base,result;
mpz_init_set_ui(base,2);
mpz_init(result);
//pow
mpz_pow_ui(result, base, 1206);
//print
gmp_printf("%Zd\n", result);
//free
mpz_clear(base);
mpz_clear(result);
return 0;
}

mul.c

include <gmp.h>

int main(){
//init
mpz_t result;
mpz_init_set_ui(result,1);

//mul
for(int i=0;i<10;i++){
	mpz_mul_ui(result, result, 20191202+i);
}

//print
gmp_printf("%Zd\n", result);
//free

mpz_clear(result);
return 0;

}

posted @ 2022-05-05 14:35  191206  阅读(760)  评论(0编辑  收藏  举报