Przejdź do zawartości

Programowanie w systemie UNIX/GMP

Z Wikibooks, biblioteki wolnych podręczników.

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

[edytuj]

Zależności

[edytuj]
sudo apt-get install m4

Rodzaje

[edytuj]

kod źródłowy

[edytuj]

Skopiuj aktualny kod ze strony GMP

Rozpakuj plik

W Ubuntu: [3][4]

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

[edytuj]
sudo apt-get install libgmp3-dev

rpm / yum

[edytuj]
sudo yum install gmp


wersje

[edytuj]
  gmp_printf("Using GMP-%s \n", gmp_version);

Położenie bibliotek

[edytuj]

Szukamy 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

[edytuj]

Biblioteka 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

[edytuj]

GMP 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

[edytuj]

Funkcje 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

[edytuj]
mpz_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

[edytuj]

Mnoż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

[edytuj]

Silnia (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)

[edytuj]

Pierwszy 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

[edytuj]

Naruszenie ochrony pamięci (core dumped)

[edytuj]
  • brak inicjalizacji zmiennej: deklaracja, nadanie wartości i usunięcie bez inicjalizacji



Źródła

[edytuj]
  1. GMP library
  2. stackoverflow.com: Write quickly GMP variables in files
  3. Instalacja GMP - Bernard Mourrain
  4. How To Install and Use GMP Library by mycodestuff
  5. gmp error while compiling mpfr on ubuntu
  6. Installation of MPFR previous versions of GMP clash
  7. ehow : how_to_install-gmp-ubunt
  8. Nomenclature and Types
  9. GMP 3.1.1 Basics
  10. on GMP By Sriram Sankaranarayanan
  11. GNU GMP examples by ElieDeBrauwer
  12. C implementation of arithmetic with arbitrarily large integers by Vasek Chvatal
  13. packages ubuntu trusty : libgmp10-doc filelist
  14. Silnia w wikipedii