Knihovna nemá žádný limit přesnosti, vyjma omezení dané dostupnou pamětí RAM. Nabízí nepřeberné množství funkcí a je implementována v jazyce C.
Já se v této části budu věnovat rozhraní v jazyce C. Než knihovnu začneme používat, musíme vložit hlavičkový soubor gmp.h
. Abychom měli k dispozici také funkce pracující s parametry FILE *
, musí tomu ještě předcházet vložení stdio.h
. Náš soubor tedy bude začínat následovně.
#include <stdio.h> #include <gmp.h>
Všechny programy využívající GMP se musejí dále linkovat oproti knihovně libgmp
(pro GCC se jedná o parametr -lgmp
).
V tomto článku se budeme věnovat pouze práci s celými čísly (integery). Datový typ v jazyce C pro celá čísla je mpz_t
. Příklady:
mpz_t integer; mpz_t vector[10];
Interně je datový typ mpz_t
definován jako jednoprvkové pole. Pokud je tohle pole předáno jako argument funkci, není předáno hodnotou, ale rozpadne se na ukazatel na první prvek pole. To znamená, že volaná funkce dostane ukazatel na hodnotu mpz_t
, což je důvod, proč není potřeba žádný operátor &
, když funkci předáváte výstupní argumenty. Velikost mpz_t
je malá. Obsahuje pouze několik velikostí a ukazatele na alokovaná data.
Každou proměnnou typu mpz_t
je třeba před použitím inicializovat. K tomu slouží funkce mpz_init
, která taktéž nastaví její počáteční hodnotu na 0. Každou inicializovanou proměnnou je třeba před ukončením programu uvolnit z paměti. K tomu slouží funkce mpz_clear
. Krátký program, který pouze inicializuje proměnnou a hned se ukončí, vypadá následovně.
#include <stdio.h> #include <gmp.h> int main() { mpz_t num; mpz_init(num); /* ... práce s proměnnou num ... */ mpz_clear(num); return 0; }
Proměnné můžeme přiřadit hodnotu pomocí funkce mpz_set_ui
, která má jako druhý argument hodnotu unsigned long int
. Další možností je přiřazení hodnoty z textového řetězce pomocí funkce mpz_set_str
, která jako druhý a třetí argument bere řetězecconst char *
a základ soustavy jako int
. Abychom viděli efekt přiřazení, vypíšeme si nastdout
aktuální hodnotu proměnné pomocí funkce gmp_printf
, která má stejné chování jako printf
. Proměnnou typumpz_t
vypíšeme pomocí konverze %Zi
.
mpz_set_ui(num, 1000000UL); gmp_printf("num = %Zi\n", num); /* vypíše num = 1000000 */ mpz_set_str(num, "1000000", 10); gmp_printf("num = %Zi\n", num); /* vypíše num = 1000000 */
Teď se dostáváme k základním aritmetickým operacím. K sečtení dvou proměnných typu mpz_t
slouží funkce mpz_add
, která bere tři parametry – proměnnou, do které uložit výsledek, dále první vstupní proměnnou a druhou vstupní proměnnou. Jednoduché užití může vypadat následovně.
mpz_t a, b, c; mpz_inits(a, b, c, NULL); mpz_set_ui(a, 2UL); mpz_set_ui(b, 3UL); mpz_add(c, a, b); /* c = a + b */ gmp_printf("%Zi\n", c); /* vypíše 5 */ mpz_clears(a, b, c, NULL);
V tomto příkladě je vidět použití funkcí mpz_inits
a mpz_clears
, které umějí inicializovat, resp. uvolnit více proměnných. Jejich výčet je zakončen pomocí hodnoty NULL
. Stejně jako pro sčítání existují funkce pro odečítání a násobení – mpz_sub
a mpz_mul
.
Stejně, jako je možné čísla násobit, je možné je také dělit. Z velkého množství funkcí si tu ukážeme tzv.tdiv
funkce, které zaokrouhlují směrem k 0, stejně jako v jazyce C. Funkce vracejí buď podíl q nebo zbytek po dělení r, pro které platí n = q * d + r, kde 0 ≤ abs® < abs(d). Funkce vracející podíl se jmenujempz_tdiv_q
a funkce vracející zbytek po dělení mpz_tdiv_r
. Jako první parametr berou proměnnou, do které uložit výsledek. Druhý parametr je n a třetí d. Uvedu příklad.
mpz_t q, n, d; mpz_inits(q, n, d, NULL); mpz_set_ui(n, 100UL); mpz_set_ui(d, 2UL); mpz_tdiv_q(q, n, d); /* q = n / d */ gmp_printf("q = %Zi\n", q); /* vypíše q = 50 */ mpz_clears(q, n, d, NULL);
Proměnné lze mezi sebou porovnávat podobně, jako používáme operátory <
, >
, <=
, >=
, ==
, !=
v jazyce C. K porovnání slouží funkce mpz_cmp
, která bere analogicky ke zmíněným operátorům v jazyce C první proměnnou op1
a druhou proměnnou op2
. Funkce vrací kladnou hodnotu pro op1 > op2, nulu pro op1 == op2, a zápornou hodnotu pro op1 < op2. Následuje malá ukázka.
if (mpz_cmp(a, b) <= 0) { /* a <= b */ } if (mpz_cmp(a, b) > 0) { /* a > b */ }
Pro práci s celými čísly existují v knihovně mnohé další funkce. Jedná se například o umocňování (mpz_powm
), odmocninu (mpz_root
), různé funkce z teorie čísel (největší společný dělitel), funkce manipulující s bity (mpz_xor
apod.), funkce pro vstup a výstup proměnných do souboru, generátory náhodných čísel a mnohé další.