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\n", 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\n", 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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM