On Fri, 18 Feb 2005 21:56:33 +1100, Richard Cavell
<> wrote:
> On 18/2/05 8:47 PM, Rolf Magnus wrote:
>
>> Seems that mpz_t is a typedef for an array. If you allocate an array with
>> new, you get a pointer to the first element, not a pointer to the array.
>> Anyway, I wonder why there would be a typedef for an array with exactly one
>> element.
>
> typedef __mpz_struct mpz_t[1];
>
> __mpz_struct is typedef'ed to a struct which has 2 ints and one pointer.
> The GMP code is too advanced for me but I'm guessing that mpz_t[1] is
> intended to point to the end of the structure rather than the start.
It's declared that way so that a C program can pass it as a sort of
reference parameter:
mpz_t a, b, c;
mpz_init2(a, 1);
mpz_init2(b, 2);
mpz_init(c);
mpz_add(c, a, b);
instead of having to put & in front of all of the variables to pass them
as pointers explicitly. Unfortunately this really messes with the types
in C++, and I wouldn't guarantee that vector<> and other containers work
properly (I remember having some problems at one time, but I'm not sure
whether they now work).
>> What do you mean? sizeof() is resolved at compile time. It _always_ returns
>> a compile-time constant.
>
> I'm making the point, though, that if I could know that sizeof() were
> constant I could create vector<mpz_t> instead of vector<mpz_t*>
Try using the C++ wrapper instead (mpz_class). Its major disadvantage
is that it sets up each variable every time it is created, including
temporaries:
mpz_class a, b, c;
a = 1;
b = "2000";
c = a + (a * b);
will allocate a temporary for (a * b) and initialise it, then throw it
away after use, calling malloc() and free(), which takes a lot of time.
If you stick to simple expressions though this won't happen (it has
optimisations so that (x = a + b; and the like are done as a single
operation). For instance, I've done timings on the following:
r = (a*b + c*d) / (a + b*c + d);
r = a*b;
tmp = c*d;
r += tmp;
tmp = b*c;
tmp += a;
tmp += d;
r /= tmp;
and the differences (on Debian GNU/Linux 'woody', Duron 1200 CPU) are a
factor of 3-4 for mpz_class and a factor of 2 for mpf_class (floating
point, both with default precision 12

. The second form is comparable
in speed to using the C GMP functions directly.
Chris C