[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