Knihovna GMP: racionální čísla a čísla s plovoucí desetinnou čárkou

3. 12. 2024
Doba čtení: 3 minuty

Sdílet

 Autor: Depositphotos
GMP (GNU MP nebo též libgmp) je matematická knihovna pro práci v libovolné přesnosti. Podíváme se na racionální čísla a čísla s plovoucí desetinnou čárkou. Ukážeme si jejich přiřazování a základní aritmetické operace.

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_dmpf_init_set_str.

bitcoin školení listopad 24

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é.

Reference

Seriál: Knihovna GMP
ikonka

Zajímá vás toto téma? Chcete se o něm dozvědět víc?

Objednejte si upozornění na nově vydané články do vašeho mailu. Žádný článek vám tak neuteče.

Autor článku

Autor vystudoval Fakultu informačních technologií VUT v Brně, kde nyní pracuje jako vědecký pracovník. Zajímá se o multimédia a na svých strojích používá výhradně Gentoo Linux.