[Gmp-commit] /var/hg/gmp: mini-gmp/tests/t-mpq_{double, str}.c: New mini-mpq t...

mercurial at gmplib.org mercurial at gmplib.org
Sun Sep 8 17:45:26 UTC 2019


details:   /var/hg/gmp/rev/6fb67d082574
changeset: 17879:6fb67d082574
user:      Marco Bodrato <bodrato at mail.dm.unipi.it>
date:      Sun Sep 08 19:13:23 2019 +0200
description:
mini-gmp/tests/t-mpq_{double,str}.c: New mini-mpq tests.

diffstat:

 mini-gmp/tests/t-mpq_double.c |  213 +++++++++++++++++++++++++++++++++++
 mini-gmp/tests/t-mpq_str.c    |  252 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 465 insertions(+), 0 deletions(-)

diffs (truncated from 473 to 300 lines):

diff -r b99e1bf5283a -r 6fb67d082574 mini-gmp/tests/t-mpq_double.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mini-gmp/tests/t-mpq_double.c	Sun Sep 08 19:13:23 2019 +0200
@@ -0,0 +1,213 @@
+/* Test mpq_set_d.
+
+Copyright 2001-2003, 2005, 2013, 2018 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library test suite.
+
+The GNU MP Library test suite is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 3 of the License,
+or (at your option) any later version.
+
+The GNU MP Library test suite is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
+
+#include <math.h>
+#include <float.h>
+
+#include "testutils.h"
+#include "../mini-mpq.h"
+
+#define COUNT 2000
+
+mp_bitcnt_t
+mpz_mantissasizeinbits (const mpz_t z)
+{
+  return ! mpz_cmp_ui (z, 0) ? 0 :
+    mpz_sizeinbase (z, 2) - mpz_scan1 (z, 0);
+}
+
+int
+mpz_abspow2_p (const mpz_t z)
+{
+  return mpz_mantissasizeinbits (z) == 1;
+}
+
+mp_bitcnt_t
+mpq_mantissasizeinbits (const mpq_t q)
+{
+  if (! mpz_abspow2_p (mpq_denref (q)))
+    return ~ (mp_bitcnt_t) 0;
+
+  return mpz_mantissasizeinbits (mpq_numref (q));
+}
+
+#if defined(DBL_MANT_DIG) && FLT_RADIX == 2
+int
+mpz_get_d_exact_p (const mpz_t z)
+{
+  return mpz_mantissasizeinbits (z) <= DBL_MANT_DIG;
+}
+
+int
+mpq_get_d_exact_p (const mpq_t q)
+{
+  /* return mpq_mantissasizeinbits (q) <= DBL_MANT_DIG; */
+  return
+    (mpz_sizeinbase (mpq_denref (q), 2) -
+     mpz_scan1 (mpq_denref (q), 0) == 1) &&
+    (mpz_sizeinbase (mpq_numref (q), 2) -
+     mpz_scan1 (mpq_numref (q), 0) <= DBL_MANT_DIG);
+  /* mpz_sizeinbase (zero, 2) - mpz_scan1 (zero, 0) == 2 */
+}
+#define HAVE_EXACT_P 1
+#endif
+
+void
+check_random (void)
+{
+  unsigned i;
+  mpz_t x;
+  mpq_t y, z;
+
+  mpz_init (x);
+  mpq_init (y);
+  mpq_init (z);
+
+  for (i = 0; i < COUNT; i++)
+    {
+      /* Use volatile, to avoid extended precision in floating point
+	 registers, e.g., on m68k and 80387. */
+      volatile double d, f;
+      unsigned long m;
+      int e, c;
+
+      mini_rrandomb (x, 8 * sizeof (unsigned long));
+      m = mpz_get_ui (x);
+      mini_urandomb (x, 8);
+      e = mpz_get_ui (x) - 128;
+
+      d = ldexp ((double) m, e);
+      mpq_set_d (y, d);
+      f = mpq_get_d (y);
+      if (f != d)
+	{
+	  fprintf (stderr, "mpq_set_d/mpq_get_d failed:\n");
+	  goto dumperror;
+	}
+
+      d = - d;
+      mpq_neg (y, y);
+
+      mpq_set_d (z, d);
+      f = mpq_get_d (z);
+      if (f != d || !mpq_equal (y, z))
+	{
+	  fprintf (stderr, "mpq_set_d/mpq_get_d failed:\n");
+	dumperror:
+	  dump ("ny", mpq_numref (y));
+	  dump ("dy", mpq_denref (y));
+	  fprintf (stderr, "m = %lx, e = %i\n", m, e);
+	  fprintf (stderr, "d = %.35g\n", d);
+	  fprintf (stderr, "f = %.35g\n", f);
+	  fprintf (stderr, "f - d = %.35g\n", f - d);
+	  abort ();
+	}
+
+      mini_rrandomb (x, 8 * sizeof (unsigned long));
+      m = mpz_get_ui (x);
+      mini_urandomb (x, 8);
+      e = mpz_get_ui (x) - 128;
+
+      d = ldexp ((double) m, e);
+      mpq_set_d (y, d);
+
+      mpq_add (y, y, z);
+      mpq_set_d (z, mpq_get_d (y));
+      f = mpq_get_d (z);
+      c = mpq_cmp (y, z);
+
+#if defined(HAVE_EXACT_P)
+      if (mpq_get_d_exact_p (y) ? c != 0 : (f > 0 ? c <= 0 : c >= 0))
+#else
+      if (f > 0 ? c < 0 : c > 0)
+#endif
+	{
+	  fprintf (stderr, "mpq_get_d/mpq_set_d failed: %i %i\n", i, c);
+	  goto dumperror;
+	}
+    }
+
+  mpz_clear (x);
+  mpq_clear (y);
+  mpq_clear (z);
+}
+
+
+void
+check_data (void)
+{
+  static const struct {
+    double        y;
+    long int      n;
+    unsigned long d;
+  } data[] = {
+    {  0.0,  0, 1 },
+    {  1.0,  1, 1 },
+    { -1.0, -1, 1 },
+    { -1.5, -3, 2 },
+    {-1.25, -5, 4 },
+    {0.125,  1, 8 },
+
+    {24685,24685,1},
+    {-9876,-9876,1},
+    {463.5,  927,2},
+
+    {1234.5/8192,  2469, 16384 },
+    {-543.0/1024,  -543,  1024 },
+    {9876.5/ 512, 19753,  1024 },
+    {9753.0/ 128,  9753,   128 },
+    {-789.0/  32,  -789,    32 },
+    {4.580078125,  2345,   512 },
+  };
+
+  mpq_t    x, r;
+  unsigned i;
+  double d;
+
+  mpq_init (x);
+  mpq_init (r);
+
+  for (i = 0; i < numberof (data); i++)
+    {
+      mpq_set_d (x, data[i].y);
+      mpq_set_si (r, data[i].n, data[i].d);
+      mpq_canonicalize (r);
+      if (!mpq_equal (x, r))
+	{
+	  fprintf (stderr, "mpq_set_d failed: %li / %lu != %g\n", data[i].n, data[i].d, data[i].y);
+	  abort ();
+	}
+      d = mpq_get_d (r);
+      if (d != data[i].y)
+	{
+	  fprintf (stderr, "mpq_get_d failed: %li / %lu != %g\n", data[i].n, data[i].d, data[i].y);
+	  abort ();
+	}
+    }
+
+  mpq_clear (x);
+  mpq_clear (r);
+}
+
+void
+testmain (int argc, char *argv[])
+{
+  check_data ();
+  check_random ();
+}
diff -r b99e1bf5283a -r 6fb67d082574 mini-gmp/tests/t-mpq_str.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mini-gmp/tests/t-mpq_str.c	Sun Sep 08 19:13:23 2019 +0200
@@ -0,0 +1,252 @@
+/*
+
+Copyright 2012-2014, 2016, 2018 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library test suite.
+
+The GNU MP Library test suite is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 3 of the License,
+or (at your option) any later version.
+
+The GNU MP Library test suite is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
+
+#include <assert.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "testutils.h"
+#include "../mini-mpq.h"
+
+#define MAXBITS 400
+#define COUNT 2000
+
+#define GMP_LIMB_BITS (sizeof(mp_limb_t) * CHAR_BIT)
+#define MAXLIMBS ((MAXBITS + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS)
+
+static void
+test_small (void)
+{
+  struct {
+    const char *input;
+    const char *decimal;
+  } data[] = {
+    { "1832407/3", "1832407/3" },
+    { " 2763959/6", "2763959/6 " },
+    { "4 981 999 / 1 8", "4981999/18" },
+    { "10\t73981/30 ", "1073981/30" },
+    { "958 544 /1", "00958544/01" },
+    { "-0", "0000" },
+    { " -000  ", "0/ 1" },
+    { "0704436/011", "231710/9" },
+    /* Check the case of large number of leading zeros. */
+    { "0000000000000000000000000/1", "0/0000000000000000000000001" },
+    { "000000000000000704436/000011", "0000000000000000231710/00009" },
+    { " 012/ 02503517", "10/689999" },
+    { "0b 10/0 1312143", "2/365667" },
+    { "-03 274062/0x1", "-882738/1" },
+    { "012\t242", "005282" },
+    { "9/0b11010111110010001111", "9/883855" },
+    { "022/ 0b11001010010100001", "18/103585" },
+    { "-0b101010110011101111/0x12", "-175343/18" },
+    { "-05/0b 111 1111 0110 1110 0110", "-5/521958" },
+    { "0b 011 111 110 111 001 000 011/0b00110", "1044035/6" },
+    { " 0x53dfc", "343548" },
+    { "-0x00012/0x000fA019", "-18/1024025" },
+    { "0x 642d1", "410321" },
+    { "0x5 8067/0Xa", "360551/10" },
+    { "-0xd6Be6/3", "-879590/3" },
+    { "\t0B1110000100000000011", "460803" },
+    { "0B\t1111110010010100101", "517285" },
+    { "-0x 00 2d/0B1\t010111101101110100", "-45/359284" },
+    { "-0B101\t1001101111111001", "-367609" },
+    { "0B10001001010111110000/0xf", "562672/15" },
+    { "0Xe4B7e/1", "936830" },
+    { "0X1E4bf/0X1", "124095" },
+    { "-0Xfdb90/05", "-1039248/5" },
+    { "0b010/0X7fc47", "2/523335" },
+    { "15/0X8167c", "15/530044" },
+    /* Some invalid inputs */
+    { "", NULL },
+    { "0x", NULL },


More information about the gmp-commit mailing list