Racionální čísla
Racionální čísla jsou zlomky ve tvaru a / b. Pro uložení racionálních čísel v libgmp slouží datový typ mpq_t. Všechny funkce v libgmp pro práci s racionálními čísly předpokládají, že jim na vstup předáte čísla v tzv. kanonickém tvaru, a také v kanonickém tvaru vracejí výsledek. Kanonický tvar znamená, že čitatel a a jmenovatel b mají gcd(a, b) = 1 a že jmenovatel je kladný. Nula má unikátní reprezentaci 0/1. Přiřazení zlomku do proměnné nekanonizuje výsledek. Je na uživateli, aby v takovém případě kanonizoval výsledek pomocí funkce mpq_canonicalize.
Inicializace a dealokaci proměnné provedeme pomocí funkcí mpq_init a mpq_clear. K nastavení hodnoty pak můžeme použít funkci mpq_set_ui, případně mpq_set_str. Příklad:
mpq_t num1, num2;
mpq_init(num1);
mpq_init(num2);
mpq_set_ui(num1, 37107UL, 1254UL);
mpq_set_str(num2, "41/152", 10);
mpq_canonicalize(num1);
mpq_canonicalize(num2);
gmp_printf("num1 = %Qi\n", num1); /* vypíše num1 = 651/22 */
gmp_printf("num2 = %Qi\n", num2); /* vypíše num2 = 41/152 */
mpq_clear(num1);
mpq_clear(num2);
Aritmetické operace
Racionální čísla můžeme samozřejmě sčítat, odčítat, násobit, dělit, apod. Ke sčítání slouží funkce mpq_add.
mpq_t num1, num2, r;
mpq_inits(num1, num2, r, NULL);
mpq_set_ui(num1, 651UL, 22UL);
mpq_set_str(num2, "41/152", 10);
mpq_add(r, num1, num2);
gmp_printf("num1 = %Qi\n", num1); /* vypíše num1 = 651/22 */
gmp_printf("num2 = %Qi\n", num2); /* vypíše num2 = 41/152 */
gmp_printf("r = %Qi\n", r); /* vypíše r = 49927/1672 */
mpq_clears(num1, num2, r, NULL);
V příkladu vidíme, že místo vícenásobného volání mpq_init a mpq_clear můžeme použít jedno volání mpq_inits a mpq_clears. Můžeme si také všimnout, že pokud přiřadíme do mpq_t již čísla v kanonickém tvaru, nemusíme volat mpq_canonicalize. Mezi další aritmetické funkce patří mpq_sub, mpq_mul a mpq_div. Reciprokou hodnotu můžeme vypočíst pomocí mpq_inv.
Operace s čitatelem a jmenovatelem
K přímému přístupu k čitateli a jmenovateli slouží makra mpq_numref a mpq_denref, které vracejí ukazatel na strukturu uvnitř mpz_t, který může být předán a modifikován funkcemi, které jsme probírali v předchozích dvou dílech seriálu. Uvedu příklad.
mpq_t number;
mpq_init(number);
mpq_set_str(number, "651/22", 10);
gmp_printf("number = %Qi\n", number); /* vypíše number = 651/22 */
mpz_add(mpq_numref(number), mpq_numref(number), mpq_denref(number));
gmp_printf("number = %Qi\n", number); /* vypíše number = 673/22 */
mpq_clear(number);
Čísla s plovoucí desetinnou čárkou
Čísla s plovoucí desetinnou čárkou jsou uložena v datovém typu mpf_t. Každé takové číslo může mít svou vlastní minimální přesnost (velikost mantisy v bitech). Přesnost, která bude použita pro nové proměnné, se nastavuje globálně pomocí funkce mpf_set_default_prec. Aby si proměnná nastavila tuhle globální minimální přesnost, musíme ji inicializovat pomocí mpf_init. Pak je tu ale ještě k dispozici funkce mpf_init2, která jako druhý argument bere minimální přesnost a nehledí tak na tu nastavenou globálně.
mpf_t x, y; mpf_init(x); /* použít globálně nastavenou minimální přesnost */ mpf_init2(y, 256); /* použít minimální přesnost 256 bitů */ /* ... */ mpf_clear(x); mpf_clear(y);
Nastavit hodnotu do proměnné mpf_t můžeme pomocí mpf_set_d, která jako druhý argument bere double. Dále máme k dispozici mpf_set_str, která bere argument v podobě textového řetězce.
mpf_t num1, num2;
mpf_inits(num1, num2, NULL);
mpf_set_d(num1, 3.141592653589793);
mpf_set_str(num2, "1.4e-10", 10);
gmp_printf("num1 = %.20Ff\n", num1);
gmp_printf("num1 = %.20Ff\n", num2);
mpf_clears(num1, num2, NULL);
Případně můžeme použít kombinovanou inicializaci a přiřazení pomocí funkcí mpf_init_set_d a mpf_init_set_str.
Aritmetické operace
Čísla s plovoucí desetinnou čárkou můžeme samozřejmě sčítat, odčítat, násobit a dělit. K tomu slouží funkce mpf_add, mpf_sub, mpf_mul a mpf_div. Pro výpočet odmocniny máme k dispozici funkci mpf_sqrt.
mpf_t r, number;
mpf_init(r);
mpf_init_set_str(number, "115", 10);
mpf_sqrt(r, number);
gmp_printf("r = %.20Ff\n", r); /* vypíše r = 10.72380529476360830480 */
mpf_clears(r, number, NULL);
Bohužel funkce jako sinus, cosinus nebo logaritmus nejsou v libgmp implementované.