zoukankan      html  css  js  c++  java
  • GMP大法教你重新做人(从入门到实战)

    一、引言

      GMP(The GNU Multiple Precision Arithmetic Library)又叫GNU多精度算术库,是一个提供了很多操作高精度的大整数,浮点数的运算的算术库,几乎没有什么精度方面的限制,功能丰富。我刚接触到这个东西的时候是在学习PHP的过程中。GMP的主要目标应用领域是密码学的应用和研究、 互联网安全应用、 代数系统、 计算代数研究等。

    二、用法介绍

      GMP详细的用法可以参考官方使用手册:https://gmplib.org/gmp-man-6.1.0.pdf,里面详细的介绍了gmp的用法。现在下面就简单的总结一下基本的用法:

      添加头文件:#include <gmp.h> 

      cmd编译命令:gcc myprogram.c -lgmp -lm -o myprogram

      声明一个gmp的整数rop :mpz_t rop;

      把字符串初始化为gmp大整数:int mpz_init_set_str(mpz_t rop, char*str, int base); 

      释放空间:void  mpz_clear(mpz_t rop);//声明了一个变量,在程序的最后一定要释放,不然会报错

      加法:void mpz_add(mpz_t rop, mpz_t op1, mpz_t op2);  //rop = op1 + op2

      减法:void mpz_sub(mpz_t rop, mpz_t op1, mpz_t op2);  //rop = op1 - op2

      乘法:void mpz_mul(mpz_t rop, mpz_t op1, mpz_t op2); //rop = op1 * op2

      除法:void mpz_cdiv_q (mpz_t q, mpz_t n, mpz_t d);  //q = n/d,这个有很多种类型,具体的看使用手册

      幂运算:void mpz_pow_ui (mpz_t rop, mpz_t base, unsigned long int exp);  //rop = base^exp

      开方:void mpz_sqrt (mpz_t rop, mpz_t op); //rop = op开方的向下取整

      ......

      以上就是gmp的基本用法,详细的还是看使用手册~~

    三、Linux/Windows下安装配置GMP

    1.Linux下安装配置GMP

      首先去官网下载gmp-6.1.2.tar.lz,官网链接为https://gmplib.org/

      将下载之后的安装包解压,在终端中输入tar -jxvf gmp-6.1.2.tar.lz

      进入gmp-6.1.2文件夹
      cd gmp-6.1.2 
      ./configure (若之后用g++ 编译则为./configure –enable-cxx )
      make
      make check
      sudo make install

      然后就可以使用啦~~~

    2.Windows下安装配置GMP

      首先是安装MinGW,它是windows版本的GCC和有用的GNU工具的集合,生成本地的Windows程序不需要第三方C运行时(C Runtime)库。在这里我们可以通过minGW安装很多东西,比如使用其安装了gcc和g++编译器和gmp大数运算库。

           在官网下载MinGW安装包:https://sourceforge.net/projects/mingw/files/MinGW/

      

      下载好后双击打开,点击"install",然后在下一步记住安装路径,默认为:C:MinGW

      

      

      然后一路点击continue,等待安装(一定要保证网络畅通),最后装完弹出下面的窗口:

      

      然后之后就可以在这里安装,不过也可以先配置环境变量,然后在cmd里直接打开也行。(这个叉掉之后还可以找回的,就在安装路径下的bin文件夹里,点击:mingw-get.exe就可以打开)

      配置环境变量:打开控制面板——>系统和安全——系统,点击左侧的“高级系统设置”,然后点击环境变量或者直接从我的电脑->属性->高级系统设置->环境变量:

    找到系统环境变量的Path,点击“编辑”,“新建”,然后把安装路径添加进去(我的系统是win10的,如果是win7的再添加之前记得加分号):

    然后就可以在命令行下打开,找到mingw32-base,右键点击——Mark for installation,然后在窗口的左上角的Installation,左键点击——Apply Changes,然后弹出窗口,点击Apply,然后装好后点击Close:

    之后以同样的方式可以把mingw32-gcc-g++和mingw32-gmp装上就可以了。

    当然也可以在命令行里安装,打开cmd,然后敲入如下指令:

    mingw-get install mingw32-base

    mingw-get install mingw32-gcc-g++

    mingw-get install mingw32-gmp

    然后在命令行里敲入gcc,或gcc -v,如果出现以下基本就配置成功了。

    四、实例讲解

      下面我们以求10000!为例说明如何使用gmp。要使用gmp必须先包含gmp的头文件:

    #include <gmp.h>

    求10000!我们需要的数据类型是整数,当然需要的是多精度整数,定义一个多精度整数(multiple precision integer)变量可以用:

    mpz_t num;

    现在我们需要定义三个变量:

    mpz_t z_i, z_s, z_o;

    分别用来迭代1..10000之间的数字、保存结果、保存1这个数字以使得z_i自增。可以用字符串来给多精度数字初始化为一个大数:

    mpz_init_set_str(z_i, "1", 10);
    mpz_init_set_str(z_s, "1", 10);
    mpz_init_set_str(z_o, "1", 10);

    mpz_init_set_str的原型是:

    int mpz_init_set_str (mpz_t rop, char *str, int base)

    这三个参数分别是多精度整数变量,字符串,进制。

    现在我们循环10000次并进行乘法和加法,乘法和加法的函数分别是mpz_mul,mpz_add,原型分别是:

    void mpz_add (mpz_t rop, mpz t op1, mpz t op2)

    效果为:rop = op1 + op2

    void mpz_mul (mpz_t rop, mpz t op1, mpz t op2)

    效果为:rop = op1 * op2

    我们的程序可以写为:

    int i;
    for (i = 0; i < 10000; i++)
    {
       mpz_mul(z_s, z_s, z_i);
       mpz_add(z_i, z_i, z_o);
    }

    然后我们按大整数的格式来输出结果,因为是mpz_t类型,不能用一般的printf,只能用gmp_printf:

    gmp_printf("%Zd
    ", z_s);

    最后我们释放这几个大整数所占的空间:

    mpz_clear(z_i);
    mpz_clear(z_s);
    mpz_clear(z_o);

    程序就完毕了。运算结果非常大,显示了几页但是速度却非常快,几乎是一秒不到就做完了还包括了在控制台打印时间。

    完整的程序如下:

     1 #include <gmp.h>
     2 #include <string.h>
     3 int main(int argc, const char *argv[])
     4 {
     5   mpz_t z_i, z_s, z_o;
     6   mpz_init_set_str(z_i, "1", 10);
     7   mpz_init_set_str(z_s, "1", 10);
     8   mpz_init_set_str(z_o, "1", 10);
     9   int i;
    10   for (i = 0; i < 10000; i++)
    11   {
    12     mpz_mul(z_s, z_s, z_i);
    13     mpz_add(z_i, z_i, z_o);
    14   }
    15   gmp_printf("%Zd
    ", z_s);
    16   mpz_clear(z_i);
    17   mpz_clear(z_s);
    18   mpz_clear(z_o);
    19   getchar();
    20   return 0;
    21 }

    我们去找到.cpp文件存放的目录下,用cmd编译命令:gcc test.cpp -lgmp -lm -o test

    此时当前文件夹会自动生成一个test.exe文件

    我们点击test.exe运行一下,可以看到结果如下所示:

    因为页数比较多,我就不全部截图了,算出这么大的一个数字,计算机编译运行打印结果花的时间不到1s,足以体现出gmp函数库的强大~~~

     对GMP深入的了解还是得多看看官方手册https://gmplib.org/gmp-man-6.1.0.pdf

  • 相关阅读:
    真正的e时代
    在线手册
    UVA 10616 Divisible Group Sums
    UVA 10721 Bar Codes
    UVA 10205 Stack 'em Up
    UVA 10247 Complete Tree Labeling
    UVA 10081 Tight Words
    UVA 11125 Arrange Some Marbles
    UVA 10128 Queue
    UVA 10912 Simple Minded Hashing
  • 原文地址:https://www.cnblogs.com/ECJTUACM-873284962/p/8350320.html
Copyright © 2011-2022 走看看