[Gmp-commit] /var/hg/gmp-proj/mini-gmp: 3 new changesets
mercurial at gmplib.org
mercurial at gmplib.org
Sat Dec 31 09:42:26 CET 2011
details: /var/hg/gmp-proj/mini-gmp/rev/f80bd2028c56
changeset: 24:f80bd2028c56
user: Niels M?ller <nisse at lysator.liu.se>
date: Sat Dec 31 09:41:13 2011 +0100
description:
Implemented mpz_fits_slong_p, mpz_fits_ulong_p, mpz_get_si,
mpz_get_ui, mpz_get_d.
details: /var/hg/gmp-proj/mini-gmp/rev/a3fd6a708515
changeset: 25:a3fd6a708515
user: Niels M?ller <nisse at lysator.liu.se>
date: Sat Dec 31 09:41:57 2011 +0100
description:
Trivial ws changes.
details: /var/hg/gmp-proj/mini-gmp/rev/7fa37b2ad847
changeset: 26:7fa37b2ad847
user: Niels M?ller <nisse at lysator.liu.se>
date: Sat Dec 31 09:42:23 2011 +0100
description:
Trimmed include list.
diffstat:
mini-gmp.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++---
mini-gmp.h | 6 ++++
tests/mini-random.c | 5 ++-
tests/t-div.c | 1 -
tests/t-double.c | 61 +++++++++++++++++++++++++++++++++++++++++++++-
5 files changed, 131 insertions(+), 10 deletions(-)
diffs (223 lines):
diff -r 00bd9d685574 -r 7fa37b2ad847 mini-gmp.c
--- a/mini-gmp.c Sat Dec 31 08:36:51 2011 +0100
+++ b/mini-gmp.c Sat Dec 31 09:42:23 2011 +0100
@@ -44,14 +44,9 @@
mpz_fdiv_qr_ui
mpz_fdiv_q_ui
mpz_fdiv_ui
- mpz_fits_slong_p
- mpz_fits_ulong_p
mpz_gcd
mpz_gcd_ui
- mpz_get_d
mpz_getlimbn
- mpz_get_si
- mpz_get_ui
mpz_hamdist
mpz_ior
mpz_lcm_ui
@@ -1700,6 +1695,69 @@
}
}
+int
+mpz_fits_slong_p (const mpz_t u)
+{
+ mp_size_t us = u->_mp_size;
+
+ if (us == 0)
+ return 1;
+ else if (us == 1)
+ return u->_mp_d[0] < (GMP_LIMB_HIGHBIT / 2);
+ else if (us == -1)
+ return u->_mp_d[0] <= (GMP_LIMB_HIGHBIT / 2);
+ else
+ return 0;
+}
+
+int
+mpz_fits_ulong_p (const mpz_t u)
+{
+ mp_size_t us = u->_mp_size;
+
+ return us == 0 || us == 1;
+}
+
+long int
+mpz_get_si (const mpz_t u)
+{
+ mp_size_t us = u->_mp_size;
+
+ if (us > 0)
+ return (long) (u->_mp_d[0] & ~GMP_LIMB_HIGHBIT);
+ else if (us < 0)
+ return (long) (- u->_mp_d[0] | GMP_LIMB_HIGHBIT);
+ else
+ return 0;
+}
+
+unsigned long int
+mpz_get_ui (const mpz_t u)
+{
+ return u->_mp_size == 0 ? 0 : u->_mp_d[0];
+}
+
+double
+mpz_get_d (const mpz_t u)
+{
+ mp_size_t un;
+ double x;
+
+ un = ABS(u->_mp_size);
+
+ if (un == 0)
+ return 0.0;
+
+ x = u->_mp_d[--un];
+ while (un > 0)
+ x = ldexp (x, GMP_LIMB_BITS) + u->_mp_d[--un];
+
+ if (u->_mp_size < 0)
+ x = -x;
+
+ return x;
+}
+
void
mpz_set_si (mpz_t r, signed long int x)
{
diff -r 00bd9d685574 -r 7fa37b2ad847 mini-gmp.h
--- a/mini-gmp.h Sat Dec 31 08:36:51 2011 +0100
+++ b/mini-gmp.h Sat Dec 31 09:42:23 2011 +0100
@@ -110,6 +110,12 @@
void mpz_setbit (mpz_t, mp_bitcnt_t);
+int mpz_fits_slong_p (const mpz_t);
+int mpz_fits_ulong_p (const mpz_t);
+long int mpz_get_si (const mpz_t);
+unsigned long int mpz_get_ui (const mpz_t);
+double mpz_get_d (const mpz_t);
+
void mpz_set_si (mpz_t, signed long int);
void mpz_set_ui (mpz_t, unsigned long int);
void mpz_set (mpz_t, const mpz_t);
diff -r 00bd9d685574 -r 7fa37b2ad847 tests/mini-random.c
--- a/tests/mini-random.c Sat Dec 31 08:36:51 2011 +0100
+++ b/tests/mini-random.c Sat Dec 31 09:42:23 2011 +0100
@@ -31,7 +31,7 @@
abort ();
}
}
-
+
void
mini_urandomb (mpz_t r, unsigned long bits)
{
@@ -41,7 +41,8 @@
free (s);
}
-void mini_rrandomb (mpz_t r, unsigned long bits)
+void
+mini_rrandomb (mpz_t r, unsigned long bits)
{
char *s;
s = hex_rrandomb (bits);
diff -r 00bd9d685574 -r 7fa37b2ad847 tests/t-div.c
--- a/tests/t-div.c Sat Dec 31 08:36:51 2011 +0100
+++ b/tests/t-div.c Sat Dec 31 09:42:23 2011 +0100
@@ -1,5 +1,4 @@
#include <assert.h>
-#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
diff -r 00bd9d685574 -r 7fa37b2ad847 tests/t-double.c
--- a/tests/t-double.c Sat Dec 31 08:36:51 2011 +0100
+++ b/tests/t-double.c Sat Dec 31 09:42:23 2011 +0100
@@ -1,11 +1,24 @@
+#include <limits.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include "mini-gmp.h"
+#include "mini-random.h"
-static const struct
+#define GMP_LIMB_BITS (sizeof(mp_limb_t) * CHAR_BIT)
+
+#define COUNT 10000
+
+static void
+dump (const char *label, const mpz_t x)
+{
+ char *buf = mpz_get_str (NULL, 16, x);
+ fprintf (stderr, "%s: %s\n", label, buf);
+ free (buf);
+}
+
+static const struct
{
double d;
const char *s;
@@ -28,6 +41,9 @@
{
unsigned i;
mpz_t x;
+
+ hex_random_init ();
+
mpz_init (x);
for (i = 0; values[i].s; i++)
@@ -46,6 +62,47 @@
}
free(s);
}
+
+ for (i = 0; i < COUNT; i++)
+ {
+ double d, f;
+ unsigned long m;
+ int e;
+
+ mini_rrandomb (x, GMP_LIMB_BITS);
+ m = mpz_get_ui (x);
+ mini_urandomb (x, 8);
+ e = mpz_get_ui (x) - 100;
+
+ d = ldexp ((double) m, e);
+ mpz_set_d (x, d);
+ f = mpz_get_d (x);
+ if (f != floor (d))
+ {
+ fprintf (stderr, "mpz_set_d/mpz_get_d failed:\n");
+ dump ("x", x);
+ fprintf (stderr, "m = %lx, e = %i\n", m, e);
+ fprintf (stderr, "d = %.15g\n", d);
+ fprintf (stderr, "f = %.15g\n", f);
+ fprintf (stderr, "d - f = %.5g\n", d - f);
+ abort ();
+ }
+ d = - d;
+
+ mpz_set_d (x, d);
+ f = mpz_get_d (x);
+ if (f != ceil (d))
+ {
+ fprintf (stderr, "mpz_set_d/mpz_get_d failed:\n");
+ dump ("x", x);
+ fprintf (stderr, "m = %lx, e = %i\n", m, e);
+ fprintf (stderr, "d = %.15g\n", d);
+ fprintf (stderr, "c = %.15g\n", f);
+ fprintf (stderr, "c - d = %.5g\n", f - d);
+ abort ();
+ }
+ }
+
mpz_clear (x);
return EXIT_SUCCESS;
}
More information about the gmp-commit
mailing list