Ciao,

On the gmp-discuss list,

Il 2020-04-11 21:41 Simon Sobisch ha scritto:
mini-gmp provides mpz_fits_slong_p ad  mpz_fits_uslingt_p, but it does
not provide the same for smaller integer types.

We can easily add the requested functions. I suggest the following code:

diff -r 805304ca965a mini-gmp/mini-gmp.c
--- a/mini-gmp/mini-gmp.c       Tue Mar 24 23:13:28 2020 +0100
+++ b/mini-gmp/mini-gmp.c       Sun Apr 19 09:47:39 2020 +0200
@@ -1565,6 +1565,32 @@
   return us >= 0 && mpn_absfits_ulong_p (u->_mp_d, us);
 }

+int
+mpz_fits_sint_p (const mpz_t u)
+{
+  return (INT_MAX + INT_MIN == 0 || mpz_cmp_ui (u, INT_MAX) <= 0) &&
+    mpz_cmpabs_ui (u, GMP_NEG_CAST (unsigned long int, INT_MIN)) <= 0;
+}
+
+int
+mpz_fits_uint_p (const mpz_t u)
+{
+  return u->_mp_size >= 0 && mpz_cmpabs_ui (u, UINT_MAX) <= 0;
+}
+
+int
+mpz_fits_sshort_p (const mpz_t u)
+{
+  return (SHRT_MAX + SHRT_MIN == 0 || mpz_cmp_ui (u, SHRT_MAX) <= 0) &&
+    mpz_cmpabs_ui (u, GMP_NEG_CAST (unsigned long int, SHRT_MIN)) <= 0;
+}
+
+int
+mpz_fits_ushort_p (const mpz_t u)
+{
+  return u->_mp_size >= 0 && mpz_cmpabs_ui (u, USHRT_MAX) <= 0;
+}
+
 long int
 mpz_get_si (const mpz_t u)
 {
diff -r 805304ca965a mini-gmp/mini-gmp.h
--- a/mini-gmp/mini-gmp.h       Tue Mar 24 23:13:28 2020 +0100
+++ b/mini-gmp/mini-gmp.h       Sun Apr 19 09:47:39 2020 +0200
@@ -244,6 +244,10 @@

 int mpz_fits_slong_p (const mpz_t);
 int mpz_fits_ulong_p (const mpz_t);
+int mpz_fits_sint_p (const mpz_t);
+int mpz_fits_uint_p (const mpz_t);
+int mpz_fits_sshort_p (const mpz_t);
+int mpz_fits_ushort_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);


I attach a patch with also the tests (somehow redundant).

Ĝis,
m
diff -r 805304ca965a mini-gmp/mini-gmp.c
--- a/mini-gmp/mini-gmp.c	Tue Mar 24 23:13:28 2020 +0100
+++ b/mini-gmp/mini-gmp.c	Sun Apr 19 09:48:28 2020 +0200
@@ -1565,6 +1565,32 @@
   return us >= 0 && mpn_absfits_ulong_p (u->_mp_d, us);
 }
 
+int
+mpz_fits_sint_p (const mpz_t u)
+{
+  return (INT_MAX + INT_MIN == 0 || mpz_cmp_ui (u, INT_MAX) <= 0) &&
+    mpz_cmpabs_ui (u, GMP_NEG_CAST (unsigned long int, INT_MIN)) <= 0;
+}
+
+int
+mpz_fits_uint_p (const mpz_t u)
+{
+  return u->_mp_size >= 0 && mpz_cmpabs_ui (u, UINT_MAX) <= 0;
+}
+
+int
+mpz_fits_sshort_p (const mpz_t u)
+{
+  return (SHRT_MAX + SHRT_MIN == 0 || mpz_cmp_ui (u, SHRT_MAX) <= 0) &&
+    mpz_cmpabs_ui (u, GMP_NEG_CAST (unsigned long int, SHRT_MIN)) <= 0;
+}
+
+int
+mpz_fits_ushort_p (const mpz_t u)
+{
+  return u->_mp_size >= 0 && mpz_cmpabs_ui (u, USHRT_MAX) <= 0;
+}
+
 long int
 mpz_get_si (const mpz_t u)
 {
diff -r 805304ca965a mini-gmp/mini-gmp.h
--- a/mini-gmp/mini-gmp.h	Tue Mar 24 23:13:28 2020 +0100
+++ b/mini-gmp/mini-gmp.h	Sun Apr 19 09:48:28 2020 +0200
@@ -244,6 +244,10 @@
 
 int mpz_fits_slong_p (const mpz_t);
 int mpz_fits_ulong_p (const mpz_t);
+int mpz_fits_sint_p (const mpz_t);
+int mpz_fits_uint_p (const mpz_t);
+int mpz_fits_sshort_p (const mpz_t);
+int mpz_fits_ushort_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);
diff -r 805304ca965a mini-gmp/tests/t-signed.c
--- a/mini-gmp/tests/t-signed.c	Tue Mar 24 23:13:28 2020 +0100
+++ b/mini-gmp/tests/t-signed.c	Sun Apr 19 09:48:28 2020 +0200
@@ -1,6 +1,6 @@
 /* Exercise some mpz_..._si functions.
 
-Copyright 2013, 2016 Free Software Foundation, Inc.
+Copyright 2013, 2016, 2020 Free Software Foundation, Inc.
 
 This file is part of the GNU MP Library test suite.
 
@@ -197,9 +197,152 @@
 }
 
 void
+try_fits_utype_p (void)
+{
+  mpz_t x;
+  mpz_init (x);
+  if (!mpz_fits_ulong_p (x))
+    {
+      printf ("mpz_fits_ulong_p (0) false!\n");
+      abort ();
+    }
+  if (!mpz_fits_uint_p (x))
+    {
+      printf ("mpz_fits_uint_p (0) false!\n");
+      abort ();
+    }
+  if (!mpz_fits_ushort_p (x))
+    {
+      printf ("mpz_fits_udhort_p (0) false!\n");
+      abort ();
+    }
+  mpz_set_si (x, -1);
+  if (mpz_fits_ulong_p (x))
+    {
+      printf ("mpz_fits_ulong_p (- 1) true!\n");
+      abort ();
+    }
+  if (mpz_fits_uint_p (x))
+    {
+      printf ("mpz_fits_uint_p (- 1) true!\n");
+      abort ();
+    }
+  if (mpz_fits_ushort_p (x))
+    {
+      printf ("mpz_fits_ushort_p (- 1) true!\n");
+      abort ();
+    }
+  mpz_set_ui (x, ULONG_MAX);
+  if (!mpz_fits_ulong_p (x))
+    {
+      printf ("mpz_fits_ulong_p (ULONG_MAX) false!\n");
+      abort ();
+    }
+  mpz_add_ui (x, x, 1);
+  if (mpz_fits_ulong_p (x))
+    {
+      printf ("mpz_fits_ulong_p (ULONG_MAX + 1) true!\n");
+      abort ();
+    }
+  mpz_set_ui (x, UINT_MAX);
+  if (!mpz_fits_uint_p (x))
+    {
+      printf ("mpz_fits_uint_p (UINT_MAX) false!\n");
+      abort ();
+    }
+  mpz_add_ui (x, x, 1);
+  if (mpz_fits_uint_p (x))
+    {
+      printf ("mpz_fits_uint_p (UINT_MAX + 1) true!\n");
+      abort ();
+    }
+  mpz_set_ui (x, USHRT_MAX);
+  if (!mpz_fits_ushort_p (x))
+    {
+      printf ("mpz_fits_ushort_p (USHRT_MAX) false!\n");
+      abort ();
+    }
+  mpz_add_ui (x, x, 1);
+  if (mpz_fits_ushort_p (x))
+    {
+      printf ("mpz_fits_ushort_p (USHRT_MAX + 1) true!\n");
+      abort ();
+    }
+
+  mpz_clear (x);
+}
+
+void
+try_fits_sint_p (void)
+{
+  mpz_t x;
+  mpz_init_set_si (x, INT_MAX);
+  if (!mpz_fits_sint_p (x))
+    {
+      printf ("mpz_fits_sint_p (INT_MAX) false!\n");
+      abort ();
+    }
+  mpz_add_ui (x, x, 1);
+  if (mpz_fits_sint_p (x))
+    {
+      printf ("mpz_fits_sint_p (INT_MAX + 1) true!\n");
+      abort ();
+    }
+  mpz_set_si (x, INT_MIN);
+  if (!mpz_fits_sint_p (x))
+    {
+      printf ("mpz_fits_sint_p (INT_MIN) false!\n");
+      abort ();
+    }
+  mpz_sub_ui (x, x, 1);
+  if (mpz_fits_sint_p (x))
+    {
+      printf ("mpz_fits_sint_p (INT_MIN - 1) true!\n");
+      abort ();
+    }
+
+  mpz_clear (x);
+}
+
+void
+try_fits_sshort_p (void)
+{
+  mpz_t x;
+  mpz_init_set_si (x, SHRT_MAX);
+  if (!mpz_fits_sshort_p (x))
+    {
+      printf ("mpz_fits_sshort_p (SHRT_MAX) false!\n");
+      abort ();
+    }
+  mpz_add_ui (x, x, 1);
+  if (mpz_fits_sshort_p (x))
+    {
+      printf ("mpz_fits_sshort_p (SHRT_MAX + 1) true!\n");
+      abort ();
+    }
+  mpz_set_si (x, SHRT_MIN);
+  if (!mpz_fits_sshort_p (x))
+    {
+      printf ("mpz_fits_sshort_p (SHRT_MIN) false!\n");
+      abort ();
+    }
+  mpz_sub_ui (x, x, 1);
+  if (mpz_fits_sshort_p (x))
+    {
+      printf ("mpz_fits_sshort_p (SHRT_MIN - 1) true!\n");
+      abort ();
+    }
+
+  mpz_clear (x);
+}
+
+void
 testmain (int argc, char *argv[])
 {
   try_fits_slong_p ();
+  try_fits_sint_p ();
+  try_fits_sshort_p ();
+  try_fits_utype_p ();
   try_op_si (-1);
   try_op_si (1);
 }
_______________________________________________
gmp-devel mailing list
gmp-devel@gmplib.org
https://gmplib.org/mailman/listinfo/gmp-devel

Reply via email to