Gnu Mpc[1] jest to biblioteka C służąca do operacji arytmetycznych na liczbach zespolonych z dowolną precyzją (ang. arbitrarily high precision) i właściwym zaokrąglaniem wyniku.

Zależności / wymagania

edytuj
  • wersja języka C: C99
  • gmp ≥ 4.3.2,
  • biblioteka MPFR, wersja mpfr ≥ 2.4.2

Instalacja

edytuj

MPC jest wbudowany w GCC od wersji 4.5, więc jeśli masz zainstalowany kompilator GCC>4.5 to bibliotekę MPC masz już zainstalowaną.

Budowanie

edytuj
./configure
make
make check 
sudo make install
make ps


lub:

./configure --prefix=/usr/local/mpc-0.9 --with-gmp=/usr/local/gmp-5.0.2 --with-mpfr=/usr/local/mpfr-3.0.1
make
make install


Wynik:

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'

Z użyciem anonimowego dostępu do git:[2]

git clone https://gforge.inria.fr/git/mpc/mpc.git


pakiety

edytuj

MPC jest również dostępne za pośrednictwem następujących pakietów stron trzecich:[3]

  • GNU Linux
    • Pakiety Debiana od Squeeze: libmpc2 dla biblioteki, libmpc-dev dla plików nagłówkowych i pakiet źródłowy mpclib
    • Pakiety Ubuntu od 09.04 (Jaunty): libmpc2 dla biblioteki i libmpc-dev dla plików nagłówkowych
    • Pakiety Opensuse od wersji 11.2: libmpc2 dla biblioteki i mpc-devel dla plików nagłówkowych
    • Pakiety Fedory w wersji rozwojowej i jako aktualizacje od wydania 11: libmpc dla biblioteki i libmpc-devel dla plików nagłówkowych
    • Pakiet Arch Linux od 2009 roku: libmpc
    • Pakiet NixOS od 0.14: mpc
    • Pakiet Guix od wydania alfa: mpc inside multiprecision
    • Pakiet zestawu kompilacji dystrybucji T2 SDE
  • Port FreeBSD, więcej informacji o Freshports
  • Pakiet Fink
  • Pakiet Cygwin mpclib


Programy:

  • Synaptic : Za pomocą Menadżera Pakietów Synaptic: libmpc (pakiet biblioteki i dev)
  • aptitude : sudo aptitude install libmpc-dev libmpc2
  • apt-get: sudo apt-get install libmpc-dev
make check

wynik:


Wejście do katalogu `/home/a/Pobrane/mpc-1.0.2/tests'
PASS: tabs
PASS: tacos
PASS: tacosh
PASS: tadd
PASS: tadd_fr
PASS: tadd_si
PASS: tadd_ui
PASS: targ
PASS: tasin
PASS: tasinh
PASS: tatan
PASS: tatanh
PASS: tconj
PASS: tcos
PASS: tcosh
PASS: tdiv
PASS: tdiv_2si
PASS: tdiv_2ui
PASS: tdiv_fr
PASS: tdiv_ui
PASS: texp
PASS: tfma
PASS: tfr_div
PASS: tfr_sub
PASS: timag
PASS: tio_str
PASS: tlog
PASS: tlog10
PASS: tmul
PASS: tmul_2si
PASS: tmul_2ui
PASS: tmul_fr
PASS: tmul_i
PASS: tmul_si
PASS: tmul_ui
PASS: tneg
PASS: tnorm
PASS: tpow
PASS: tpow_ld
PASS: tpow_d
PASS: tpow_fr
PASS: tpow_si
PASS: tpow_ui
PASS: tpow_z
PASS: tprec
PASS: tproj
PASS: treal
PASS: treimref
PASS: tset
PASS: tsin
PASS: tsin_cos
PASS: tsinh
PASS: tsqr
PASS: tsqrt
PASS: tstrtoc
PASS: tsub
PASS: tsub_fr
PASS: tsub_ui
PASS: tswap
PASS: ttan
PASS: ttanh
PASS: tui_div
PASS: tui_ui_sub
GMP: include 6.0.0, lib 6.0.0
MPFR: include 3.1.1-p2, lib 3.1.1-p2
MPC: include 1.0.2, lib 1.0.2
C compiler: gcc -std=gnu99
GCC: yes
GCC version: 4.8
PASS: tget_version
===================
All 64 tests passed
===================

Precyzja

edytuj
mpfr_prec_t


Zaokrąglenie

edytuj

Sposoby zaokrąglanie (ang. rounding Modes) liczb zespolonych typu mpc_t mają formę:[4]

MPC_RNDxy  

Litery x i y oznaczają sposób dla części rzeczywistej (litera x) i urojonej (litera y) Są następujące metody:

  • N oznacza do najbliższej liczby (to nearest)
  • Z w kierunku zera (towards zero)
  • U w (towards plus infinity)
  • D (towards minus infinity)


zmienna określająca jet typu:

mpc_rnd_t

Format liczb

edytuj
  • liczba zmiennoprzecinkowa (brakująca część urojona jest ustawiona na +0)
  • para liczb zmiennoprzecinkowych:
    • oddzielonych spacją
    • otoczona nawiasami


Przedrostki określające podstawę formatu liczb:

  • '0b' dla liczb dwójkowych (ang. binary numbers)
  • '0x' dla liczb heksadecymalnych (ang. hexadecimal numbers)
  • bez przedrostka dla liczb dziesiętnych
"If base = 0, then a prefix may be used to indicate the base in which the floating-point number is written.
...
The real and imaginary part may then be written in different bases. For instance, "(1.024e+3 +2.05e+3)" and "(0b1p+10 +0x802)" are valid strings for base=0 and represent the same value."

Przykłady poprawnych liczb dziesiętnych (ang. base = 10):

3.1415926 
(1.25e+7 +.17) 
(@nan@ 2) 
(-0 -7) 
-@inf@


binarnych:

0b101
(0b101 0b1.01)

Definicja

typedef struct {
mpfr_t re;
mpfr_t im;
} __mpc_struct;
typedef __mpc_struct mpc_t[1];

Każda część (rzeczywista i urojona) ma swoją precyzję [5]


Dostęp do części:

mpc_realref (z)
mpc_imagref (z)

Funkcja

edytuj
mpc_conj: x - iy
mpc_norm: x^2 + y^2
mpc_abs: sqrt(x^2 + y^2) 

Zwracana wartość: inex

edytuj
inex = inexact value

"Most MPC functions have a return value of type int, which is used to indicate the position of the rounded real and imaginary parts with respect to the exact (infinite precision) values. If this integer is k, the macros MPC_INEX_RE(k) and MPC_INEX_IM(k) give 0 if the corresponding rounded value is exact, a negative value if the rounded value is less than the exact one, and a positive value if it is greater than the exact one. Similarly, functions computing a result of type mpfr_t return an integer that is 0, positive or negative depending on whether the rounded value is the same, larger or smaller then the exact result"

Jak używać w c ?

edytuj

Etapy użycia:[6]

  • deklaracja zmiennej
  • inicjalizacja
  • przypisanie (ang. Assignment)
  • obliczenia (ang. computing)
  • zwolnienie pamięci (ang. freeing)


//declaration
mpc_t z
// Initialisation
mpc_init2 (z, prec)
//Assignment
mpc_set
//Computation
//Freeing
mpc_clear (z)


Najprostszy przykład:[7]

// gcc foo.c -lmpc

#include "mpc.h"

int main() {
    mpc_t x; // declaration
    mpc_init2 (x, 256); // Initialisation
    // Assignment ( here nothing )
    // Computation ( here nothing )
    mpc_clear (x); // Freeing
    return 0;
}

Kompilacja:

gcc ... -lmpc -lmpfr -lgmp ...

Przykłady

edytuj
#include <stdio.h>
#include <gmp.h>
#include <mpfr.h>
#include <mpc.h>


/* 
  
 LD_LIBRARY_PATH=/usr/local/include
export LD_LIBRARY_PATH

to compile (from Linux console) 
  Link your program with libaries : MPC , MPFR and GMP.
  MPFR library reference (-lmpfr) should be before GMP's one (-lgmp) :

 gcc mpc.c  -lmpc -lmpfr -lgmp

 and run :

  ./a.out


*/

int main (void)
 {
       mpc_t x, y;
       mpc_init2 (x, 256);		/* precision exactly 256 bits */
       mpc_init3 (y, 100, 50);	/* 100/50 bits for the real/imaginary part */
       mpc_clear (x);
       mpc_clear (y);
     }

wersja

edytuj
/*

gcc m.c -lmpc -mpfr -lgmp -Wall

*/
#include <stdio.h>
#include <gmp.h>
#include <mpfr.h>
#include "mpc.h"

int main() {
    
    mpfr_printf(" MPC-%s \nMPFR-%s \n GMP-%s \n", MPC_VERSION_STRING, mpfr_version, gmp_version );
    return 0;
}


Przykładowy wynik


 MPC-1.1.0 
MPFR-4.0.2 
 GMP-6.2.0 


asin(2i)

edytuj

Funkcja asin oblicza arcsine z liczby całkowitej:

/*

https://www.gnu.org/ghm/2011/paris/slides/andreas-enge-mpc.pdf

gcc a.c  -lmpc -lmpfr -lgmp

*/


#include <stdio.h>
#include <gmp.h>
#include <mpfr.h>
#include <mpc.h>
 
 
int main (void) {
 
mpc_t z; // input value = op
int inex; // return value of the function ( not the result of computation )
mpc_t r; // output value = rop : r=f(z)
 
 
mpc_init2 (z, 123);
mpc_init2 (r, 123); 
 
mpc_set_ui_ui (z, 0, 2, MPC_RNDNN); // z = 0 + 2i
 
//  
inex = mpc_asin (r, z, MPC_RNDNN);  // r = asin(z)
 
printf ("asin");
mpc_out_str (stdout, 10, 0, z, MPC_RNDNN);
printf (" = ");
mpc_out_str (stdout, 10, 0, r, MPC_RNDNN);
printf ("  \n");
printf ("inex = %i %i\n", MPC_INEX_RE (inex), MPC_INEX_IM (inex));
 
 
mpc_clear(z);
mpc_clear(r);
}

Wynik:


asin(0 2.00000000000000000000000000000000000000) = (0 1.44363547517881034249327674027310526938)  
inex = 0 -1

mpc_set_str

edytuj
/*
 
https://www.gnu.org/ghm/2011/paris/slides/andreas-enge-mpc.pdf
 
gcc s.c  -lmpc -lmpfr -lgmp
 
*/
 
 
#include <stdio.h>
#include <gmp.h>
#include <mpfr.h>
#include <mpc.h>



int DescribeInex(int inex)
{
printf ("inex = %d ; %i %i\n", inex, MPC_INEX_RE (inex), MPC_INEX_IM (inex));
if (inex==-1) printf(" bad input string \n\n") ;
else {if (MPC_INEX_RE (inex)==0) printf(" real part  value is exact as the input \n");
      if (MPC_INEX_RE (inex)<0) printf(" rounded real part  value is  less than the exact one input \n");
      if (MPC_INEX_RE (inex)>0) printf(" rounded real part  value is  grater than the exact one input \n");
      if (MPC_INEX_IM (inex)==0) printf(" imag part  value is exact as the input \n");
      if (MPC_INEX_IM (inex)<0) printf(" rounded imag part  value is  less than the exact one input \n");
      if (MPC_INEX_IM (inex)>0) printf(" rounded imag part  value is  grater than the exact one input \n");
      printf("  \n");
      }
 
return 0; 


}
 
 
int main (void) {
 
mpc_t z; // input value = op


int inex; // return value of the function ( not the result of computation )
//mpc_t r; // output value = rop : r=f(z)
 
// 
mpc_init2 (z, 123);
//mpc_init2 (r, 123); 


//   bad input  
inex = mpc_set_str (z, "(-1.8605aaa7396001587505e+00 -0.00000093437424500e+00)",10, MPC_RNDNN); // read z value from string 
// print result  
printf ("z = "); mpc_out_str (stdout, 10, 0, z, MPC_RNDNN); printf ("  \n");
printf ("z = "); mpfr_out_str (stdout, 10, 0, mpc_realref (z), MPFR_RNDD); printf (" ;  "); mpfr_out_str (stdout, 10, 0, mpc_imagref (z), MPFR_RNDD); printf (" \n "); 
DescribeInex( inex);


//   bad input  
inex = mpc_set_str (z, "(aa7396001587505e+00 -0.00000ggg093437424500e+00)",10, MPC_RNDNN); // read z value from string 
// print result  
printf ("z = "); mpc_out_str (stdout, 10, 0, z, MPC_RNDNN); printf ("  \n");
printf ("z = "); mpfr_out_str (stdout, 10, 0, mpc_realref (z), MPFR_RNDD); printf (" ;  "); mpfr_out_str (stdout, 10, 0, mpc_imagref (z), MPFR_RNDD); printf (" \n "); 
DescribeInex( inex);


//   good input  
inex = mpc_set_str (z, "(-1.86057396001587505e+00 -0.00000093437424500e+00)",10, MPC_RNDNN); // read z value from string 
// print result  
printf ("z = "); mpc_out_str (stdout, 10, 0, z, MPC_RNDNN); printf ("  \n");
printf ("z = "); mpfr_out_str (stdout, 10, 0, mpc_realref (z), MPFR_RNDD); printf (" ;  "); mpfr_out_str (stdout, 10, 0, mpc_imagref (z), MPFR_RNDD); printf (" \n "); 
DescribeInex( inex);


//   good input  
inex = mpc_set_str (z, "(-1 -0.00000093437424500e+00)",10, MPC_RNDNN); // read z value from string 
// print result  
printf ("z = "); mpc_out_str (stdout, 10, 0, z, MPC_RNDNN); printf ("  \n");
printf ("z = "); mpfr_out_str (stdout, 10, 0, mpc_realref (z), MPFR_RNDD); printf (" ;  "); mpfr_out_str (stdout, 10, 0, mpc_imagref (z), MPFR_RNDD); printf (" \n "); 
DescribeInex(inex);


//   good binary input  
inex = mpc_set_str (z, "0b101",0, MPC_RNDNN); // read z value from string 
// print result  
printf ("z = "); mpc_out_str (stdout, 2, 0, z, MPC_RNDNN); printf ("  \n");
printf ("z = "); mpfr_out_str (stdout, 2, 0, mpc_realref (z), MPFR_RNDD); printf (" ;  "); mpfr_out_str (stdout, 2, 0, mpc_imagref (z), MPFR_RNDD); printf (" \n "); 
DescribeInex(inex);


//   good binary input ; If base = 0, then a prefix may be used to indicate the base in which the floating-point number is written.
inex = mpc_set_str (z, "(0b101 0b1.01)",0, MPC_RNDNN); // read z value from string 
// print result  
printf ("z = "); mpc_out_str (stdout, 2, 0, z, MPC_RNDNN); printf ("  \n");
printf ("z = "); mpfr_out_str (stdout, 2, 0, mpc_realref (z), MPFR_RNDD); printf (" ;  "); mpfr_out_str (stdout, 2, 0, mpc_imagref (z), MPFR_RNDD); printf (" \n "); 
DescribeInex(inex);
 
mpc_clear(z);
//mpc_clear(r);
}

Źródła

edytuj
  1. GNU Mpc
  2. Source Code Repository for MPC (Multiple Precision Complex)
  3. mpc packages
  4. MPC doc: 4.4 Rounding Modes
  5. Introduction to the GNU MPC library (Andreas Enge)
  6. The MPC library - a quick introduction by Andreas Enge
  7. Stackoverflow: How I compile MPC code?