1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
|
GMPAda makes the GNU MultiPrecision library usable with the Ada
language.
Extensive documentation about the GMP original C library can be found
at http://gmplib.org/manual.
The latest source is available on https://nicolas.boulenguez.free.fr.
--------------------- Usage --------------------------
The demo subdirectory contains a test program. It is first intended as
a test for the library, almost without user-readable output. Though,
reading the source file "demo.adb" will give you an idea of how this
library works. Once it is well installed, you can compile your
programs with the gprbuild tool as described in the installed project,
or use gnatmake as shown in the Makefile for the test target.
A static library and a dynamic library are provided, but if you want
the best performances, you should recompile your program using the
library source and the -O2 -gnatn switches, as inlining is very
efficient for the thin binding part.
-------------------- Status ---------------------
Big_Integer and Big_Float operations are available and coherent.
Big_Rationals operations are usable.
--------------- What is GMPAda? ---------------
The GNU_Multiple_Precision package provides the type Big_Integer
allowing integer computations without other space limitation than your
computer's memory.
Initialization, assignement and finalization are provided by a
controlled type. Equivalent of operations and attributes that you
might expect when used to Ada.Standard.Integer and Ada.Standard.Float
are provided.
One day, there would be Big_Rationals and Big_Complexes childs, but
for the moment the former learns philosophy while the later is in
therapy.
The child packages named Random_Numbers, Text_IO, Wide_Text_IO,
Wide_Wide_Text_IO provide the services documented in the Ada Reference
Manual for Ada child packages with the same names (actually, there
are some subtle differences, see Random_Numbers and Generic_Text_IO
specifications).
The Text_IO packages are generic instantiations. This allows each
user to set its own Default_Width and Default_Base by making its own
instantiation, as with Ada.Text_IO subpackages, if it is ever
necessary. There are (better) technical reasons too, see the
Implementation below.
----------- Important performance note -----------------
You should see these Ada types as limited if you seek performance.
Each assignement allocates then frees space for temporary objects,
eating much execution time.
Quickly said: if you mind performance, write
Set (A, B); instead of A := B;
Add (A, A, C); instead of A := A + C;
Then, why allow assignment, and equivalent of Ada.Standard attributes
and primitive operations? For users who need readable code and do not
care for execution speed. I originally needed long integers and a
readable language like Ada for educational purpose.
-------------- Data exchange with C streams ---------------
The Ada Stream attributes of Big_Integer respect the raw format used
by the library for the C mpz_t type.
The Big_Rational type provides sensible Stream attributes, but without
C raw IO equivalents. This library writes the numerator then the
denominator (as Big_Integers=mpz_t).
Stream attributes for Big_Float will not do anything useful, and would
anyway have no C equivalent.
--------- Implementation -----------------
The GMP hierarchy is for internal purpose. The GNU_Multiple_Precision
hierarchy exports controlled types.
The GCC C++ compiler generates the gmp_h.ads Ada header, which defines
types compatible with the C library. It is currently unable to define
most functions.
The C library "gmp_macros" expands gmp C preprocessor macros into C
functions, so that they can be imported to Ada and linked. Rewriting
them is an easy temptation, but the former solution is portable and
GMP-version independant. It avoids depending on the internal
structure of mp[tqf]_t C types. There is no significative efficiency
counterpart since the imported procedures can be explicitely inlined
if profiling shows it is necessary (and if the compiler does not do it
during optimization).
The Ada package "GMP.Binding" imports the C types and functions from
gmp.h. It is only intended as a step to build a controlled
abstraction. I cannot see who would benefit from a thin binding like
that anyway. The visible part should only contain informations
gathered in the normative part of the documentation. With GNAT, an
array is passed by reference. This is compatible with a C one-element
array like mpz_t. I hope this won't chage for a while, since "access"
mode instead of "in, out, in out" modes would be much less
readable. Types like mpz_t should be limited, but this would make
another dereference mandatory in the controlled abstraction (a
significative performance hit), or make it limited too (many users
would miss slow but readable "+" overloading), and I think both prices
are too high.
The private part and the body may vary with the gmp version. Namely,
they depend on mpz_t internal structure (for raw input) and GMP raw IO
format (for raw input and output). I cannot see how to rewrite the
Read procedure using only the gmp.h procedures without a huge
performance hit. That would remove the dependance on the mpz_t
internal structure. The binding would be simplier and depend less on
the gmp version (raw IO changes are rare, since C users do not like
them either). Help appreciated.
Types visible by Ada users are controlled, so that initialization and
finalization are handled automatically. Text Input-Output is rewritten
from scratch, with generic packages avoiding code repetition for wide
versions. It allows giving the IO format described by the ARM. Only
change with ARM, each expected out mode parameter is made an "in out"
mode parameter to avoid unuseful Finalization-Initialization.
All types are declared in the same parent package, so that conversions
of private extensions are possible. It avoids that the conversion
programs depend on two tagged type and try to dispatch twice, too...
Suggestions welcome.
------------ Credits ------------
Thanks to Michael Roe and Gisle Saelensmind for providing their work
on the net. This work is inspired by theirs, to say the least.
Thanks to Jerome Delcourt for assembling documentation and links
concerning big numbers in Ada.
Thanks to Ludovic Brenta for providing a readable example of project
file in its debian packaging of gtkada.
Thanks to Vincent Diemunsch for helping to merge his similar work and
correcting bugs.
Thanks for Bernard Weisser for reporting some bugs.
----- Alternative bindings (updated 2013) -----
As mentioned above, this binding should strictly extend Gisle
Saelensmind's work (not available anymore), and Michael Roe's
GNU_Multiple_Precision
http://www.chiark.greenend.org.uk/~mroe/Ada/GMP/index.html
http://code.google.com/p/adabindinggmpmpfr/
Vincent Diemunsch has written a similar work, focusing on MPFR.
http://svn.eu.adacore.com/anonsvn/Dev/trunk/gps/gnatlib/src/gmp/gnatcoll-gmp-integers.ads
Adacore has reimplemented parts of this binding.
|