Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

gmp hello world

87 views
Skip to first unread message

luser droog

unread,
Jun 3, 2016, 1:34:32 AM6/3/16
to
It's alive! It's alive!

//number.c
//$make number LDLIBS='-lgmp'
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <gmp.h>

void nothing(mpz_t c, const mpz_t a, const mpz_t b){
mpz_set_ui(c,0);
}

int main(){
char op[2];
//scanf("%d %1s %d", &a, op, &b);
mpz_t az,bz,cz;
mpz_init(az);
mpz_init(bz);
mpz_init(cz);
gmp_scanf("%Zd %1s %Zd", &az, op, &bz);
( (*op=='+')?mpz_add:
(*op=='*')?mpz_mul:
nothing ) (cz, az, bz);
gmp_printf("%Zd\n", cz);
}

--
My creature is alive!

luser droog

unread,
Jun 3, 2016, 1:42:36 AM6/3/16
to
On Friday, June 3, 2016 at 12:34:32 AM UTC-5, luser droog wrote:
> It's alive! It's alive!
>
> //number.c
> //$make number LDLIBS='-lgmp'
> #include <stdarg.h>
> #include <stdint.h>
> #include <stdio.h>
> #include <gmp.h>

> gmp_scanf("%Zd %1s %Zd", &az, op, &bz);

Don't need the `&`s. Since the `mpz_t` is an
array [1] of a struct type, (char*)(az) == (char*)(&az).
So it doesn't hurt anything, I think.

Barry Schwarz

unread,
Jun 3, 2016, 4:46:12 AM6/3/16
to
The fact that the two expressions will compare equal after the cast is
irrelevant since nothing in your code will perform that conversion.

%Zd is not a standard format for scanf functions. Does it mean the
same as %zd? Whatever it means, are you sure your struct is properly
aligned for that data type? Is the first member of the struct a type
compatible with this format?

While we are at it, are you absolutely certain that a pointer to your
struct or a pointer to an array of your struct have the same size and
representation as a pointer to whatever the data type %Zd requires.

--
Remove del for email

luser droog

unread,
Jun 3, 2016, 3:38:33 PM6/3/16
to
On Friday, June 3, 2016 at 3:46:12 AM UTC-5, Barry Schwarz wrote:
> On Thu, 2 Jun 2016 22:42:26 -0700 (PDT), luser droog
> <luser...@gmail.com> wrote:
>
> >On Friday, June 3, 2016 at 12:34:32 AM UTC-5, luser droog wrote:
> >> It's alive! It's alive!
> >>
> >> //number.c
> >> //$make number LDLIBS='-lgmp'
> >> #include <stdarg.h>
> >> #include <stdint.h>
> >> #include <stdio.h>
> >> #include <gmp.h>
> >
> >> gmp_scanf("%Zd %1s %Zd", &az, op, &bz);
> >
> >Don't need the `&`s. Since the `mpz_t` is an
> >array [1] of a struct type, (char*)(az) == (char*)(&az).
> >So it doesn't hurt anything, I think.
>
> The fact that the two expressions will compare equal after the cast is
> irrelevant since nothing in your code will perform that conversion.

That part was my (mistaken) rationalization for why the additional `&`s
still appeared to work correctly. The documentation does not use `&`.

> %Zd is not a standard format for scanf functions.

It's an extension implemented by the gmp_scanf and gmp_printf which
correspond to mpz_t parameters.

>Does it mean the
> same as %zd? Whatever it means, are you sure your struct is properly
> aligned for that data type? Is the first member of the struct a type
> compatible with this format?
>
> While we are at it, are you absolutely certain that a pointer to your
> struct or a pointer to an array of your struct have the same size and
> representation as a pointer to whatever the data type %Zd requires.

I'm confident that following the documentation will remove much of my
need for this level of scrutiny.

luser droog

unread,
Jun 4, 2016, 8:48:40 PM6/4/16
to
On Friday, June 3, 2016 at 2:38:33 PM UTC-5, luser droog wrote:
> On Friday, June 3, 2016 at 3:46:12 AM UTC-5, Barry Schwarz wrote:
> > On Thu, 2 Jun 2016 22:42:26 -0700 (PDT), luser droog
> > <luser...@gmail.com> wrote:
> >
> > >On Friday, June 3, 2016 at 12:34:32 AM UTC-5, luser droog wrote:
> > >> It's alive! It's alive!
> > >>

> I'm confident that following the documentation will remove much of my
> need for this level of scrutiny.

A little more fleshed-out. 4-function calculator. Produces floating-point
results for division, but only accepts integer input.

//number.c
//$make number LDLIBS='-lmpfr -lgmp'
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <mpfr.h>
#include <gmp.h>

enum tag { NONE, Z, FR };

typedef union {
enum tag tag;
struct z {
enum tag tag;
mpz_t z;
} z;
struct fr {
enum tag tag;
mpfr_t fr;
} fr;
} u_number;
typedef u_number number[1];
typedef u_number *number_ptr;

void init_z(number_ptr z){
z->z.tag = Z;
mpz_init(z->z.z);
}

void init_fr(number_ptr fr){
fr->fr.tag = FR;
mpfr_init(fr->fr.fr);
}

void promote(number_ptr n){
mpz_t t;
memcpy(&t, &n->z.z, sizeof t);
init_fr(n);
mpfr_set_z(n->fr.fr, t, MPFR_RNDN);
mpz_clear(t);
}

#define op(func, C, A, B) \
if ((A)->tag==Z && (B)->tag==Z) { \
if (!strcmp(#func,"div")) { \
init_fr(C); \
promote(A); \
promote(B); \
mpfr_##func((C)->fr.fr, (A)->fr.fr, (B)->fr.fr, MPFR_RNDN); \
} else { \
init_z(C); \
mpz_##func((C)->z.z, (A)->z.z, (B)->z.z); \
} \
} else if ((A)->tag==FR && (B)->tag==FR) { \
init_fr(C); \
mpfr_##func((C)->fr.fr, (A)->fr.fr, (B)->fr.fr, MPFR_RNDN); \
}

void mpz_nothing(mpz_t c, const mpz_t a, const mpz_t b){
mpz_set_ui(c,0);
}

void mpfr_nothing(mpfr_t c, const mpfr_t a, const mpfr_t b, mpfr_rnd_t rnd){
mpfr_set_ui(c,0,rnd);
}

int main(){
number a, b, c;
char op[2];
init_z(a);
init_z(b);

gmp_scanf("%Zd %1s %Zd", a->z.z, op, b->z.z);
switch(*op){
case '+': op(add, c, a, b); break;
case '*': op(mul, c, a, b); break;
case '-': op(sub, c, a, b); break;
case '/': op(div, c, a, b); break;
default: op(nothing, c, a, b);
}
switch(c->tag){
case Z: gmp_printf("%Zd\n", c->z.z); break;
case FR: mpfr_printf("%Rf\n", c->fr.fr); break;
}
}

Tim Rentsch

unread,
Jun 15, 2016, 6:16:11 PM6/15/16
to
Probably it will work, but technically it is undefined behavior,
because the type of pointer passed doesn't match the type
expected.

Real Troll

unread,
Jun 15, 2016, 6:30:55 PM6/15/16
to
Is this no good for you these days? !!!!!!!!!!!!!!!!!

#include <stdio.h>
#include <conio.h>

int main()
{
printf("Hello World!!!");
printf("Press any key to continue ...");
getch();
}


0 new messages