Programowanie w systemie UNIX/GMP
GNU Multiple Precision Arithmetic Library (lub GMP)[1] - biblioteka programistyczna udostępniająca liczby całkowite, wymierne i zmiennoprzecinkowe o dowolnej precyzji. Wewnętrzny format danych jest binarny.[2]
Instalacja
edytujZależności
edytujsudo apt-get install m4
Rodzaje
edytujkod źródłowy
edytujSkopiuj aktualny kod ze strony GMP
Rozpakuj plik
./configure make make check sudo make install
Libraries have been installed in: /usr/local/lib If you ever happen to want to link against installed libraries in a given directory, LIBDIR, you must either use libtool, and specify the full pathname of the library, or use the '-LLIBDIR' flag during linking and do at least one of the following: - add LIBDIR to the 'LD_LIBRARY_PATH' environment variable during execution - add LIBDIR to the 'LD_RUN_PATH' environment variable during linking - use the '-Wl,-rpath -Wl,LIBDIR' linker flag - have your system administrator add LIBDIR to '/etc/ld.so.conf'
apt-get
edytujsudo apt-get install libgmp3-dev
rpm / yum
edytujsudo yum install gmp
wersje
edytujgmp_printf("Using GMP-%s \n", gmp_version);
Położenie bibliotek
edytujSzukamy bibliotek: [5]
ls -l /usr/lib/libgmp*
przykładowy wynik:
ls: nie ma dostępu do /usr/lib/libgmp*: Nie ma takiego pliku ani katalogu
ls -l /usr/local/lib/libgmp*
przykładowy wynik:
-rw-r--r-- 1 root root 1293344 wrz 23 17:31 /usr/local/lib/libgmp.a -rwxr-xr-x 1 root root 914 wrz 23 17:31 /usr/local/lib/libgmp.la lrwxrwxrwx 1 root root 16 wrz 23 17:31 /usr/local/lib/libgmp.so -> libgmp.so.10.2.0 lrwxrwxrwx 1 root root 16 wrz 23 17:31 /usr/local/lib/libgmp.so.10 -> libgmp.so.10.2.0 -rwxr-xr-x 1 root root 531957 wrz 23 17:31 /usr/local/lib/libgmp.so.10.2.0
dpkg --list | grep gmp
przykładowy wynik:
ii libgmp-dev:amd64 2:5.1.2+dfsg-2ubuntu1 amd64 Multiprecision arithmetic library developers tools ii libgmp10:amd64 2:5.1.2+dfsg-2ubuntu1 amd64 Multiprecision arithmetic library ii libgmp10:i386 2:5.1.2+dfsg-2ubuntu1 i386 Multiprecision arithmetic library ii libgmpxx4ldbl:amd64 2:5.1.2+dfsg-2ubuntu1 amd64 Multiprecision arithmetic library (C++ bindings)
Z użyciem locate: [6]
sudo updatedb locate libgmp
przykładowy wynik:
/home/a/.tor-browser-en/INSTALL/Tor/libgmp.so /home/a/.tor-browser-en/INSTALL/Tor/libgmp.so.10 /home/a/.tor-browser-en/INSTALL/Tor/libgmp.so.10.1.3 /home/a/.tor-browser-en/INSTALL/Tor/libgmpxx.so /home/a/.tor-browser-en/INSTALL/Tor/libgmpxx.so.4 /home/a/.tor-browser-en/INSTALL/Tor/libgmpxx.so.4.3.3 /usr/lib/i386-linux-gnu/libgmp.so.10 /usr/lib/i386-linux-gnu/libgmp.so.10.1.2 /usr/lib/x86_64-linux-gnu/libgmp.so.10 /usr/lib/x86_64-linux-gnu/libgmp.so.10.1.2 /usr/lib/x86_64-linux-gnu/openssl-1.0.0/engines/libgmp.so /usr/share/doc/libgmp10 /usr/share/doc/libgmp10/README.Debian /usr/share/doc/libgmp10/changelog.Debian.gz /usr/share/doc/libgmp10/copyright /var/lib/dpkg/info/libgmp10:amd64.list /var/lib/dpkg/info/libgmp10:amd64.md5sums /var/lib/dpkg/info/libgmp10:amd64.postinst /var/lib/dpkg/info/libgmp10:amd64.postrm /var/lib/dpkg/info/libgmp10:amd64.shlibs /var/lib/dpkg/info/libgmp10:i386.list /var/lib/dpkg/info/libgmp10:i386.md5sums /var/lib/dpkg/info/libgmp10:i386.postinst /var/lib/dpkg/info/libgmp10:i386.postrm /var/lib/dpkg/info/libgmp10:i386.shlibs
Ubuntu
edytujBiblioteka GMP po instalacji ze źródeł będzie zainstalowana w katalogu[7]:
/usr/local/lib
Starsza wersja biblioteki pozostanie w:
/usr/lib/i386-linux-gnu/ # on 32-bit systems /usr/lib/x86_64-linux-gnu/ # on 64-bit systems
Jeśli twój program potrzebuje nowszej wersji to musisz go skonfigurować tak, aby szukał w katalogu:
/usr/local/lib
inaczej będzie korzystała ze starej wersji GMP
Typy danych
edytujGMP używa własnych typów danych dla liczb wielokrotnej precyzji:[8]
- mpz_t dla liczb całkowitych
- mpq_t dla liczby wymiernych (C nie ma takiego typu)
- mpf_t dla liczb zmiennoprzecinkowych
- mp_exp_t dla wykładników (ang. exponent) (odpowiada long int)
- mp_limb_t ("A limb means the part of a multi-precision number that fits in a single word. (We chose this word because a limb of the human body is analogous to a digit, only larger, and containing several digits.) Normally a limb contains 32 or 64 bits.")[9]
Pozostałe typy:
- mp_size_t
- gmp_randstate_t
- size_t
- mp_bitcnt_t = typ dla oznaczenia precyzji liczby zmiennoprzecinkowej. ("Counts of bits of a multi-precision number are represented in the C type mp_bitcnt_t. Currently this is always an unsigned long, but on some systems it will be an unsigned long long in the future.")
Funkcje
edytujFunkcje dla danego typu mają nazwę o tym samym przedrostku, np:
- mpz_init dla typu mpz_t
- mpq_init dla typu mpq_t
- mpf_init dla typu mpf_t
Możemy:
- inicjować kilka zmiennych tego samego typu jednocześnie:
mpf_inits(sq_me, sq_out, test, NULL);
- inicjować i jednocześnie nadać wartość jednej zmiennej:
mpz_init_set_ui
- usunąć kilka zmiennych jednocześnie:
mpf_clears(sq_me, sq_out, test, NULL);
Używamy listy zmiennych zakończonej NULL
.
Schemat programu
edytuj- deklaracja zmiennej
- inicjacja zmiennej (ang. init)
- przypisanie wartości (ang. set)
- przetwarzanie zmiennej
- usunięcie zmiennej (ang. clear)
/*
skeleton of the gmp code by Sriram Sankaranarayanan
http://www.cs.colorado.edu/~srirams/classes/doku.php/gmp_usage_tutorial
gcc g.c -lgmp -Wall
./a.out
*/
#include <gmp.h>
int main(void){
mpz_t n;
mpz_init(n);
mpz_set_ui(n,0);
/* tu wstaw kod przetwarzający zmienną n */
mpz_clear(n);
gmp_printf (" GMP-%s \n ", gmp_version );
return 0;
}
init
edytujmpz_set_str(z, "33877456965431938318210482471113262183356704085033125021829876006886584214655562", 10 ); // jeśli z > ui_max
mpz_set_ui(z, 6886584214655562); // jeśli z < ui_max
mpz_set_str (sq_me, argv[1], 10); // wczytywanie z listy argumentów
mpf_init2(avg, prec),
Powinno się sprawdzać poprawność inicjalizacji, przykład:
// mpfr_set_str function returns 0 if the entire string up to the final null character is a valid number in base base; otherwise it returns -1 set_result = mpfr_set_str(v, xs, 0, GMP_RNDN); if ( set_result < 0) { // error printf( "view line not valid, check chars \n"); // free memory because return without free is causing a memory leak free(xs); }
Przykłady
edytuj- lista przykładów [10] [11][12]
- pakiet libgmp10-doc zawiera przykładowe programy, które można znaleźć w katalogu: /usr/share/doc/libgmp10-doc/examples/demos/[13]
Liczby całkowite
edytujMnożenie
edytuj// gcc m.c -lgmp
// ./a.out
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
int main(void)
{
mpz_t x;
mpz_t y;
mpz_t result;
mpz_init(x);
mpz_init(y);
mpz_init(result);
mpz_set_str(x, "7612058254738945", 10);
mpz_set_str(y, "9263591128439081", 10);
mpz_mul(result, x, y);
gmp_printf("\n"
" %Zd\n"
"*\n"
" %Zd\n"
"--------------------\n"
"%Zd\n"
"\n", x, y, result);
/* free used memory */
mpz_clear(x);
mpz_clear(y);
mpz_clear(result);
return EXIT_SUCCESS;
}
Wynik:
7612058254738945
*
9263591128439081
--------------------
70514995317761165008628990709545
Silnia
edytujSilnia (ang. factorial) [14]
// http://www.mersenneforum.org/showthread.php?t=3970
// C programme which will compute factorials
#include <stdio.h>
#include <gmp.h>
int main (int argc, char **argv)
{
mpz_t x;
mpz_init (x);
mpz_fac_ui (x, atoi (argv[1]));
gmp_printf ("%Zd\n", x);
mpz_clear (x);
return 0;
}
Zapisujemy jako f.c
i kompilujemy:
gcc f.c -lgmp
Uruchamiamy:
./a.out 10
Otrzymujemy wynik:
3628800
Bardziej skomplikowany przykład:
./a.out 100 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
Tablica
edytuj/*
http://stackoverflow.com/questions/26908628/gmp-mpz-array-init-is-an-obsolete-function-how-should-we-initialize-mpz-arrays
gcc a.c -lgmp
*/
#include <stdlib.h> // malloc
#include <stdio.h>
#include <gmp.h>
int main ()
{
int array_size = 100;
int i;
mpz_t *array;
mpz_t temp;
// allocate memory for the array
array = malloc(array_size * sizeof(mpz_t));
if (NULL == array) {
printf("ERROR: Out of memory\n");
return 1;
}
// init
mpz_init(temp);
for (i = 0; i < array_size; i++) {
mpz_init2(array[i], 1024);
}
// compute
// using string and temp variable
mpz_set_str (temp, "20023232323232323234343434", 10);
mpz_set(array[10], temp);
// using ui
mpz_set_ui(array[12], 1212121);
// check
gmp_printf ("%Zd\n",array[10]); //
gmp_printf ("%Zd\n", temp); //
gmp_printf ("%Zd\n",array[12]); //
// free memory
for (i = 0; i < array_size; i++) {
mpz_clear(array[i]);
}
free(array);
mpz_clear(temp);
return 0;
}
Liczby wymierne (dziesiętne i binarne)
edytujPierwszy przykład
edytuj/*
C programme using gmp
gcc r.c -lgmp
http://gmplib.org/manual/Rational-Number-Functions.html#Rational-Number-Functions
*/
#include <stdio.h>
#include <gmp.h>
// input = num/den
unsigned int num = 1;
unsigned int den = 6;
int main ()
{
mpq_t q; // rational number;
int b =2 ; // base of numeral system
mpz_t n ;
mpz_t d ;
mpf_t f ;
char *sr;
char *sf;
mp_exp_t exponent ; // holds the exponent for the result string
// init and set variables
mpq_init (q); // Initialize r and set it to 0/1.
mpf_init (f);
mpz_init_set_ui(n,num);
mpz_init_set_ui(d,den);
mpq_set_num(q,n);
mpq_set_den(q,d);
mpq_canonicalize (q); // It is the responsibility of the user to canonicalize the assigned variable before any arithmetic operations are performed on that variable.
mpf_set_q(f,q);
// convertions
sr = mpq_get_str (NULL, b, q); // rational number = fraction : from decimal to binary
// If str is NULL, the result string is allocated using the current allocation function
sf = mpf_get_str (NULL, &exponent, b, 0, f); // floating point number : from decimal to binary
// If n_digits is 0 then that accurate maximum number of digits are generated.
// print
gmp_printf ("a rational number %Zd / %Zd is in a canonical form ( decimal fraction) : %Qd\n",n,d, q); //
gmp_printf(" numerator of rational number = %Zd \n", mpq_numref(q)); //
gmp_printf(" denominator of rational number = %Zd \n", mpq_denref(q)); //
gmp_printf (" binary rational ( string ) : %s \n", sr); //
gmp_printf (" decimal floating point number : %.Ff \n", f); //
// The output of the GMP programme is in the form mantissa,'e',exponent where the value is
// 0.mantissa * 2^exponent
// GMP represents the floating point numbers (for base 2) as a pair of exponent and mantissa (and sign).
//The generated string is a fraction, with an implicit radix point immediately to the left of the first digit.
// Trailing zeros are not returned.
// For example, the number 3.1416 would be returned as string "31416" and exponent 1 so :
// 3.1416 = 0.31416*10^1
// another example : 1/6 as a exponential form of binary number will be :
// mantissa = 101010101010101010101010101010101010101010101010101010101010101011
// exponet = -2
// so 1/6 = 0.101010101010101010101010101010101010101010101010101010101010101011 * 2 ^(-2) = 0.0(01)
gmp_printf (" mantissa of binary floating ( string ) : %s \n", sf); //
gmp_printf (" exponent : %ld \n", exponent); //
printf ("binary floating number in exponential form =0.%s*%d^%ld\n", sf,b, exponent);
// clear memory
mpq_clear (q);
mpz_clear (n);
mpz_clear (d);
mpf_clear (f);
return 0;
}
Kompilujemy:
gcc r.c -lgmp
Uruchamiamy
./a.out
Otrzymujemy:
a rational number 1 / 6 is in a canonical form ( decimal fraction) : 1/6 numerator of rational number = 1 denominator of rational number = 6 binary rational ( string ) : 1/110 decimal floating point number : 0.166666666666666666667 mantissa of binary floating ( string ) : 101010101010101010101010101010101010101010101010101010101010101011 exponent : -2 binary floatin in exponential form =0.101010101010101010101010101010101010101010101010101010101010101011*2^-2
Proste obliczenia
edytuj// gcc d.c -lgmp -Wall
#include <stdio.h>
#include <gmp.h>
// a multiple precision integer, as defined by the GMP library. The C data type for such integers is mpz_t
int print_z(mpz_t z, int base, char *s){
printf("%s= ", s);
mpz_out_str (stdout, 10, z);
printf (" for base = %d\n", base);
return 0;
}
// rop = (2*op) mod 1
// wikipedia : dyadic_transformation or doubling map
void mpq_doubling(mpq_t rop, const mpq_t op)
{
mpz_t n; // numerator
mpz_t d; // denominator
mpz_inits(n, d, NULL);
//
mpq_get_num (n, op); //
mpq_get_den (d, op);
// n = (n * 2 ) % d
mpz_mul_ui(n, n, 2);
mpz_mod( n, n, d);
// output
mpq_set_num(rop, n);
mpq_set_den(rop, d);
mpz_clears(n, d, NULL);
}
int main ()
{
int i;
//
unsigned long int e = 89; // exponent is also a period of doubling map
unsigned long int b = 2;
// arbitrary precision variables from GMP library
mpz_t n ; // numerator of q
mpz_t d ; // denominator of q
mpq_t q; // rational number q = n/d
// init and set variables
mpz_init_set_ui(n, 1);
// d = (2^e) -1
// http://fraktal.republika.pl/mset_external_ray.html
mpz_init(d);
mpz_ui_pow_ui(d, b, e) ; // d = b^e
mpz_sub_ui(d, d, 1); // d = d-1
// q = n/d
mpq_init (q); //
mpq_set_num(q,n);
mpq_set_den(q,d);
mpq_canonicalize (q); // It is the responsibility of the user to canonicalize the assigned variable before any arithmetic operations are performed on that variable.
// print
//print_z(d, 10, "d ");
//print_z(n, 10, "n ");
gmp_printf ("q = %Qd\n",q); //
//
for (i=0; i<(1+2*e) ; i++){
mpq_doubling(q, q);
gmp_printf ("q = %Qd\n",q); //
}
// clear memory
mpq_clear (q);
mpz_clears(n, d, NULL);
return 0;
}
Wynik:
q = 1/618970019642690137449562111 q = 2/618970019642690137449562111 q = 4/618970019642690137449562111 q = 8/618970019642690137449562111 q = 16/618970019642690137449562111 q = 32/618970019642690137449562111 q = 64/618970019642690137449562111 q = 128/618970019642690137449562111 q = 256/618970019642690137449562111 q = 512/618970019642690137449562111 q = 1024/618970019642690137449562111 q = 2048/618970019642690137449562111 q = 4096/618970019642690137449562111 q = 8192/618970019642690137449562111 q = 16384/618970019642690137449562111 q = 32768/618970019642690137449562111 q = 65536/618970019642690137449562111 q = 131072/618970019642690137449562111 q = 262144/618970019642690137449562111 q = 524288/618970019642690137449562111 q = 1048576/618970019642690137449562111 q = 2097152/618970019642690137449562111 q = 4194304/618970019642690137449562111 q = 8388608/618970019642690137449562111 q = 16777216/618970019642690137449562111 q = 33554432/618970019642690137449562111 q = 67108864/618970019642690137449562111 q = 134217728/618970019642690137449562111 q = 268435456/618970019642690137449562111 q = 536870912/618970019642690137449562111 q = 1073741824/618970019642690137449562111 q = 2147483648/618970019642690137449562111 q = 4294967296/618970019642690137449562111 q = 8589934592/618970019642690137449562111 q = 17179869184/618970019642690137449562111 q = 34359738368/618970019642690137449562111 q = 68719476736/618970019642690137449562111 q = 137438953472/618970019642690137449562111 q = 274877906944/618970019642690137449562111 q = 549755813888/618970019642690137449562111 q = 1099511627776/618970019642690137449562111 q = 2199023255552/618970019642690137449562111 q = 4398046511104/618970019642690137449562111 q = 8796093022208/618970019642690137449562111 q = 17592186044416/618970019642690137449562111 q = 35184372088832/618970019642690137449562111 q = 70368744177664/618970019642690137449562111 q = 140737488355328/618970019642690137449562111 q = 281474976710656/618970019642690137449562111 q = 562949953421312/618970019642690137449562111 q = 1125899906842624/618970019642690137449562111 q = 2251799813685248/618970019642690137449562111 q = 4503599627370496/618970019642690137449562111 q = 9007199254740992/618970019642690137449562111 q = 18014398509481984/618970019642690137449562111 q = 36028797018963968/618970019642690137449562111 q = 72057594037927936/618970019642690137449562111 q = 144115188075855872/618970019642690137449562111 q = 288230376151711744/618970019642690137449562111 q = 576460752303423488/618970019642690137449562111 q = 1152921504606846976/618970019642690137449562111 q = 2305843009213693952/618970019642690137449562111 q = 4611686018427387904/618970019642690137449562111 q = 9223372036854775808/618970019642690137449562111 q = 18446744073709551616/618970019642690137449562111 q = 36893488147419103232/618970019642690137449562111 q = 73786976294838206464/618970019642690137449562111 q = 147573952589676412928/618970019642690137449562111 q = 295147905179352825856/618970019642690137449562111 q = 590295810358705651712/618970019642690137449562111 q = 1180591620717411303424/618970019642690137449562111 q = 2361183241434822606848/618970019642690137449562111 q = 4722366482869645213696/618970019642690137449562111 q = 9444732965739290427392/618970019642690137449562111 q = 18889465931478580854784/618970019642690137449562111 q = 37778931862957161709568/618970019642690137449562111 q = 75557863725914323419136/618970019642690137449562111 q = 151115727451828646838272/618970019642690137449562111 q = 302231454903657293676544/618970019642690137449562111 q = 604462909807314587353088/618970019642690137449562111 q = 1208925819614629174706176/618970019642690137449562111 q = 2417851639229258349412352/618970019642690137449562111 q = 4835703278458516698824704/618970019642690137449562111 q = 9671406556917033397649408/618970019642690137449562111 q = 19342813113834066795298816/618970019642690137449562111 q = 38685626227668133590597632/618970019642690137449562111 q = 77371252455336267181195264/618970019642690137449562111 q = 154742504910672534362390528/618970019642690137449562111 q = 309485009821345068724781056/618970019642690137449562111 q = 1/618970019642690137449562111 q = 2/618970019642690137449562111 q = 4/618970019642690137449562111
Wczytywanie danych z łańcucha
edytuj// gcc d.c -lgmp -Wall
#include <stdio.h>
#include <gmp.h>
// a multiple precision integer, as defined by the GMP library. The C data type for such integers is mpz_t
int print_z(mpz_t z, int base, char *s){
printf("%s", s);
mpz_out_str (stdout, 10, z);
//printf (" for base = %d\n", base);
printf ("\n");
return 0;
}
void mpq_doubling(mpq_t rop, const mpq_t op)
{
mpz_t n; // numerator
mpz_t d; // denominator
mpz_inits(n, d, NULL);
//
mpq_get_num (n, op); //
mpq_get_den (d, op);
// n = (n * 2 ) % d
mpz_mul_ui(n, n, 2);
mpz_mod( n, n, d);
// output
mpq_set_num(rop, n);
mpq_set_den(rop, d);
mpz_clears(n, d, NULL);
}
int main ()
{
// input = number as a string
char *snd = "179622968672387565806504265";
int i;
//
unsigned long int e = 89; // exponent is also a period of doubling map
unsigned long int b = 2;
// arbitrary precision variables from GMP library
mpz_t n ; // numerator of q
mpz_t d ; // denominator of q
mpq_t q; // rational number q = n/d
// init and set variables
mpz_inits(n, d, NULL);
mpz_set_str(n, snd, 10);
// d = (2^e) -1
mpz_ui_pow_ui(d, b, e) ; // d = b^e
mpz_sub_ui(d, d, 1); // d = d-1
// q = n/d
mpq_init (q); //
mpq_set_num(q,n);
mpq_set_den(q,d);
mpq_canonicalize (q); // It is the responsibility of the user to canonicalize the assigned variable before any arithmetic operations are performed on that variable.
// print
print_z(n, 10, "");
//
for (i=0; i<(2+e) ; i++){
mpq_doubling(q, q);
mpq_get_num(n,q); // mpq_get_num (MP_INT *numerator, MP_RAT *rational_number)
print_z(n, 10, "");
}
// clear memory
mpq_clear (q);
mpz_clears(n, d, NULL);
return 0;
}
Wynik:
179622968672387565806504265 359245937344775131613008530 99521855046860125776454949 199043710093720251552909898 398087420187440503105819796 177204820732190868762077481 354409641464381737524154962 89849263286073337598747813 179698526572146675197495626 359397053144293350394991252 99824086645896563340420393 199648173291793126680840786 399296346583586253361681572 179622673524482369273801033 359245347048964738547602066 99520674455239339645642021 199041348910478679291284042 398082697820957358582568084 177195375999224579715574057 354390751998449159431148114 89811484354208181412734117 179622968708416362825468234 359245937416832725650936468 99521855190975313852310825 199043710381950627704621650 398087420763901255409243300 177204821885112373368924489 354409643770224746737848978 89849267897759356026135845 179698535795518712052271690 359397071591037424104543380 99824123539384710759524649 199648247078769421519049298 399296494157538843038098596 179622968672387548626635081 359245937344775097253270162 99521855046860057056978213 199043710093720114113956426 398087420187440228227912852 177204820732190319006263593 354409641464380638012527186 89849263286071138575492261 179698526572142277150984522 359397053144284554301969044 99824086645878971154375977 199648173291757942308751954 399296346583515884617503908 179622673524341631785445705 359245347048683263570891410 99520674454676389692220709 199041348909352779384441418 398082697818705558768882836 177195375994720980088203561 354390751989441960176407122 89811484336193782903252133 179622968672387565806504266 359245937344775131613008532 99521855046860125776454953 199043710093720251552909906 398087420187440503105819812 177204820732190868762077513 354409641464381737524155026 89849263286073337598747941 179698526572146675197495882 359397053144293350394991764 99824086645896563340421417 199648173291793126680842834 399296346583586253361685668 179622673524482369273809225 359245347048964738547618450 99520674455239339645674789 199041348910478679291349578 398082697820957358582699156 177195375999224579715836201 354390751998449159431672402 89811484354208181413782693 179622968708416362827565386 359245937416832725655130772 99521855190975313860699433 199043710381950627721398866 398087420763901255442797732 177204821885112373436033353 354409643770224746872066706 89849267897759356294571301 179698535795518712589142602 359397071591037425178285204 99824123539384712907008297 199648247078769425814016594 399296494157538851628033188
Konwersje
edytuj/*
C programme using gmp
gcc r.c -lgmp -Wall
./a.out
http://gmplib.org/manual/Rational-Number-Functions.html#Rational-Number-Functions
*/
#include <stdio.h>
#include <gmp.h>
int main ()
{
// input = binary fraction as a string
char *sbr = "01001010010010100101001001010010010100101001001010010100100101001001010010100100101001010/11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111";
mpq_t q; // rational number;
int b =2 ; // base of numeral system
mpz_t n ;
mpz_t d ;
mpf_t f;
// init and set variables
mpq_init (q); // Initialize r and set it to 0/1.
mpq_set_str (q, sbr , b);
mpq_canonicalize (q); // It is the responsibility of the user to canonicalize the assigned variable before any arithmetic operations are performed on that variable.
mpq_canonicalize (q); // It is the responsibility of the user to canonicalize the assigned variable before any arithmetic operations are performed on that variable.
// n , d
mpz_inits(n,d,NULL);
mpq_get_num(n,q);
mpq_get_den(d, q);
//
mpf_init2(f, 100); // http://stackoverflow.com/questions/12804362/gmp-division-precision-or-printing-issue
mpf_set_q(f,q); // There is no rounding, this conversion is exact.
// print
gmp_printf ("decimal fraction = %Zd / %Zd \ndecimal canonical form = %Qd\n",n,d, q); //
gmp_printf ("binary fraction = %s \n", sbr); //
gmp_printf ("decimal floating point number : %.30Ff \n", f); //
// clear memory
mpq_clear (q);
mpz_clear (n);
mpz_clear (d);
mpf_clear (f);
return 0;
}
Wynik:
decimal fraction = 179622968672387565806504266 / 618970019642690137449562111 decimal canonical form = 179622968672387565806504266/618970019642690137449562111 binary fraction = 01001010010010100101001001010010010100101001001010010100100101001001010010100100101001010/11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 decimal floating point number : 0.290196557138708685358212602171
Liczby zmiennoprzecinkowe
edytuj// http://stackoverflow.com/questions/822734/square-root-of-bignum-using-gmp?rq=1
// gcc f.c -lgmp
#include <stdlib.h>
#include <stdio.h>
#include "gmp.h"
void usage(const char *progname) {
fprintf(stderr,
"usage: %s number \n"
"example : \n %s 12\n", progname, progname);
}
int main (int argc, char *argv[]) {
// read and check input
if (argc < 2) { usage(argv[0]); return 1; }
//
mpf_t sq_me, sq_out, test;
mpf_set_default_prec (1000);
mpf_inits(sq_me, sq_out, test, NULL); /* use default precision */
mpf_set_str (sq_me, argv[1], 10); // read ffrom input
mpf_sqrt(sq_out, sq_me); // sq_out = sqrt(sq_me)
mpf_mul(test,sq_out,sq_out); //test = sq_out * sq_out
gmp_printf ("Input: %Ff\n\n", sq_me);
gmp_printf ("Square root: %.200Ff\n\n", sq_out);
gmp_printf ("Re-squared: %Ff\n\n", test);
mpf_clears(sq_me, sq_out, test, NULL);
return 0;
}
Przykładowe dane wejściowe:
Input: 2452466449002782119765176635730880184670267876783327597434144 51715061600830038587216952208399332071549103626827191679864079776723243005 60059203563124656121846581790410013185929961993381701214933503487587055106 7.000000 Square root: 4952238331303110980924222615988628334869566046038127132471492 86806548130939472399634016783775955618921028.19202568258368255653837168412 92356432661548614332014106174638951390596672950394981098992388116308833260 04535647648563996144250924277757344248059826024201642748515325655438898558 17807282091590722890002 Re-squared: 2452466449002782119765176635730880184670267876783327597434144 51715061600830038587216952208399332071549103626827191679864079776723243005 60059203563124656121846581790410013185929961993381701214933503487587055106 7.000000
Rozwiązywanie problemów
edytujNaruszenie ochrony pamięci (core dumped)
edytuj- brak inicjalizacji zmiennej: deklaracja, nadanie wartości i usunięcie bez inicjalizacji
Źródła
edytuj- ↑ GMP library
- ↑ stackoverflow.com: Write quickly GMP variables in files
- ↑ Instalacja GMP - Bernard Mourrain
- ↑ How To Install and Use GMP Library by mycodestuff
- ↑ gmp error while compiling mpfr on ubuntu
- ↑ Installation of MPFR previous versions of GMP clash
- ↑ ehow : how_to_install-gmp-ubunt
- ↑ Nomenclature and Types
- ↑ GMP 3.1.1 Basics
- ↑ on GMP By Sriram Sankaranarayanan
- ↑ GNU GMP examples by ElieDeBrauwer
- ↑ C implementation of arithmetic with arbitrarily large integers by Vasek Chvatal
- ↑ packages ubuntu trusty : libgmp10-doc filelist
- ↑ Silnia w wikipedii