emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 0c850df888e 13/17: Optimize smallish mpz to native int conversion


From: Paul Eggert
Subject: master 0c850df888e 13/17: Optimize smallish mpz to native int conversion
Date: Thu, 11 Jul 2024 10:01:59 -0400 (EDT)

branch: master
commit 0c850df888ebb68096a82ab32089e809de591620
Author: Paul Eggert <eggert@cs.ucla.edu>
Commit: Paul Eggert <eggert@cs.ucla.edu>

    Optimize smallish mpz to native int conversion
    
    * src/bignum.c (make_integer_mpz, mpz_to_intmax):
    If FASTER_BIGNUM, optimize the common case where the value fits in
    long int.  In this case we can use mpz_fits_slong_p and mpz_get_si
    instead of looping with mpz_getlimbn.
    (mpz_to_uintmax): Likewise for unsigned long int and mpz_get_ui.
---
 src/bignum.c | 34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/src/bignum.c b/src/bignum.c
index 1fe195d78ea..7589691dd0c 100644
--- a/src/bignum.c
+++ b/src/bignum.c
@@ -145,9 +145,19 @@ make_neg_biguint (uintmax_t n)
 Lisp_Object
 make_integer_mpz (void)
 {
+  if (FASTER_BIGNUM && mpz_fits_slong_p (mpz[0]))
+    {
+      long int v = mpz_get_si (mpz[0]);
+      if (!FIXNUM_OVERFLOW_P (v))
+       return make_fixnum (v);
+    }
+
   size_t bits = mpz_sizeinbase (mpz[0], 2);
 
-  if (bits <= FIXNUM_BITS)
+  if (! (FASTER_BIGNUM
+        && FIXNUM_OVERFLOW_P (LONG_MIN)
+        && FIXNUM_OVERFLOW_P (LONG_MAX))
+      && bits <= FIXNUM_BITS)
     {
       EMACS_INT v = 0;
       int i = 0, shift = 0;
@@ -216,6 +226,17 @@ mpz_set_uintmax_slow (mpz_t result, uintmax_t v)
 bool
 mpz_to_intmax (mpz_t const z, intmax_t *pi)
 {
+  if (FASTER_BIGNUM)
+    {
+      if (mpz_fits_slong_p (z))
+       {
+         *pi = mpz_get_si (z);
+         return true;
+       }
+      if (LONG_MIN <= INTMAX_MIN && INTMAX_MAX <= LONG_MAX)
+       return false;
+    }
+
   ptrdiff_t bits = mpz_sizeinbase (z, 2);
   bool negative = mpz_sgn (z) < 0;
 
@@ -246,6 +267,17 @@ mpz_to_intmax (mpz_t const z, intmax_t *pi)
 bool
 mpz_to_uintmax (mpz_t const z, uintmax_t *pi)
 {
+  if (FASTER_BIGNUM)
+    {
+      if (mpz_fits_ulong_p (z))
+       {
+         *pi = mpz_get_ui (z);
+         return true;
+       }
+      if (UINTMAX_MAX <= ULONG_MAX)
+       return false;
+    }
+
   if (mpz_sgn (z) < 0)
     return false;
   ptrdiff_t bits = mpz_sizeinbase (z, 2);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]