一、引言
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