This is the mail archive of the guile@sourceware.cygnus.com mailing list for the Guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: scm_pseudolong vs. scm_longdigs


On Fri, 14 Apr 2000, Dirk Herrmann wrote:

> thus I tried to get rid of the distinction with the attached patch to
> current cvs.  Surprisingly, after applying the patch, performance goes

Ooops, forgot to attach the patch, sorry.

Dirk
Index: numbers.c
===================================================================
RCS file: /cvs/guile/guile/guile-core/libguile/numbers.c,v
retrieving revision 1.77
diff -u -r1.77 numbers.c
--- numbers.c	2000/04/11 13:00:15	1.77
+++ numbers.c	2000/04/14 08:52:38
@@ -74,6 +74,25 @@
 #define isfinite(x) (!IS_INF (x) && (x) == (x))
 #endif
 
+
+typedef union {
+  long l;
+  SCM_BIGDIG bd[SCM_DIGSPERLONG];
+} inum2big;
+
+
+#define BIGGIFY_LONG(source, target) \
+  { long __abs_source = source < 0 ? -source : source; \
+    scm_sizet __i = 0; \
+    \
+    for (__i = 0; __i < SCM_DIGSPERLONG; ++__i) { \
+      target.bd[__i] = SCM_BIGLO (__abs_source); \
+      __abs_source = SCM_BIGDN (__abs_source); \
+    } \
+  }
+
+#define BIGGIFIED_DIGITS(d) (d.bd)
+
 
 
 
@@ -229,18 +248,11 @@
 	  scm_divbigdig (SCM_BDIGITS (sw), SCM_NUMDIGS (sw), (SCM_BIGDIG) z);
 	  return scm_normbig (sw);
 	} else {
-#ifndef SCM_DIGSTOOBIG
-	  long w = scm_pseudolong (z);
-	  return scm_divbigbig (SCM_BDIGITS (x), SCM_NUMDIGS (x),
-				(SCM_BIGDIG *) & w, SCM_DIGSPERLONG,
-				SCM_BIGSIGN (x) ? (yy > 0) : (yy < 0), 2);
-#else
-	  SCM_BIGDIG zdigs[SCM_DIGSPERLONG];
-	  scm_longdigs (z, zdigs);
+	  inum2big zdigs;
+	  BIGGIFY_LONG (z, zdigs);
 	  return scm_divbigbig (SCM_BDIGITS (x), SCM_NUMDIGS (x),
-				zdigs, SCM_DIGSPERLONG,
+				BIGGIFIED_DIGITS (zdigs), SCM_DIGSPERLONG,
 				SCM_BIGSIGN (x) ? (yy > 0) : (yy < 0), 2);
-#endif
 	}
       }
     }
@@ -769,18 +781,15 @@
 	  bady: SCM_WTA (SCM_ARG2, n2);
 # endif
   intbig: {
-# ifndef SCM_DIGSTOOBIG
-    long z = scm_pseudolong(SCM_INUM(n1));
-    if ((n1 < 0) && SCM_BIGSIGN(n2))
-      return scm_big_ior((SCM_BIGDIG *)&z, SCM_DIGSPERLONG, SCM_BIGSIGNFLAG, n2);
-    return scm_big_and((SCM_BIGDIG *)&z, SCM_DIGSPERLONG, (n1 < 0) ? SCM_BIGSIGNFLAG : 0, n2, 0);
-# else
-    SCM_BIGDIG zdigs[SCM_DIGSPERLONG];
-    scm_longdigs(SCM_INUM(n1), zdigs);
-    if ((n1 < 0) && SCM_BIGSIGN(n2))
-      return scm_big_ior(zdigs, SCM_DIGSPERLONG, SCM_BIGSIGNFLAG, n2);
-    return scm_big_and(zdigs, SCM_DIGSPERLONG, (n1 < 0) ? SCM_BIGSIGNFLAG : 0, n2, 0);
-# endif
+    inum2big zdigs;
+    BIGGIFY_LONG (SCM_INUM (n1), zdigs);
+    if ((n1 < 0) && SCM_BIGSIGN (n2)) {
+      return scm_big_ior (BIGGIFIED_DIGITS (zdigs), SCM_DIGSPERLONG,
+			  SCM_BIGSIGNFLAG, n2);
+    } else {
+      return scm_big_and(BIGGIFIED_DIGITS (zdigs), SCM_DIGSPERLONG,
+			 (n1 < 0) ? SCM_BIGSIGNFLAG : 0, n2, 0);
+    };
   }}
 #else
   SCM_ASRTGO(SCM_INUMP(n1), badx);
@@ -825,22 +834,19 @@
   if SCM_NINUMP(n2) {
 # ifndef SCM_RECKLESS
     if (!(SCM_NIMP(n2) && SCM_BIGP(n2)))
-    bady: SCM_WTA(SCM_ARG2, n2);
-# endif
-  intbig: {
-# ifndef SCM_DIGSTOOBIG
-    long z = scm_pseudolong(SCM_INUM(n1));
-    if ((!(n1 < 0)) && !SCM_BIGSIGN(n2))
-      return scm_big_ior((SCM_BIGDIG *)&z, SCM_DIGSPERLONG, (n1 < 0) ? SCM_BIGSIGNFLAG : 0, n2);
-    return scm_big_and((SCM_BIGDIG *)&z, SCM_DIGSPERLONG, (n1 < 0) ? SCM_BIGSIGNFLAG : 0, n2, SCM_BIGSIGNFLAG);
-# else
-    BIGDIG zdigs[DIGSPERLONG];
-    scm_longdigs(SCM_INUM(n1), zdigs);
-    if ((!(n1 < 0)) && !SCM_BIGSIGN(n2))
-      return scm_big_ior(zdigs, SCM_DIGSPERLONG, (n1 < 0) ? SCM_BIGSIGNFLAG : 0, n2);
-    return scm_big_and(zdigs, SCM_DIGSPERLONG, (n1 < 0) ? SCM_BIGSIGNFLAG : 0, n2, SCM_BIGSIGNFLAG);
+      bady: SCM_WTA(SCM_ARG2, n2);
 # endif
-  }}
+  intbig: 
+    {
+      inum2big zdigs;
+      BIGGIFY_LONG (SCM_INUM(n1), zdigs);
+      if ((!(n1 < 0)) && !SCM_BIGSIGN(n2))
+	return scm_big_ior (BIGGIFIED_DIGITS (zdigs), SCM_DIGSPERLONG,
+			    (n1 < 0) ? SCM_BIGSIGNFLAG : 0, n2);
+      return scm_big_and (BIGGIFIED_DIGITS (zdigs), SCM_DIGSPERLONG, 
+			  (n1 < 0) ? SCM_BIGSIGNFLAG : 0, n2, SCM_BIGSIGNFLAG);
+    }
+  }
 #else
   SCM_ASRTGO(SCM_INUMP(n1), badx);
   SCM_ASSERT(SCM_INUMP(n2), n2, SCM_ARG2, FUNC_NAME);
@@ -892,20 +898,15 @@
   }
   if SCM_NINUMP(n2) {
 # ifndef SCM_RECKLESS
-  if (!(SCM_NIMP(n2) && SCM_BIGP(n2)))
-  bady: SCM_WTA (SCM_ARG2, n2);
-# endif
-  intbig: 
-      {
-# ifndef SCM_DIGSTOOBIG
-	  long z = scm_pseudolong(SCM_INUM(n1));
-	  return scm_big_xor((SCM_BIGDIG *)&z, SCM_DIGSPERLONG, (n1 < 0) ? SCM_BIGSIGNFLAG : 0, n2);
-# else
-	  SCM_BIGDIG zdigs[SCM_DIGSPERLONG];
-	  scm_longdigs(SCM_INUM(n1), zdigs);
-	  return scm_big_xor(zdigs, SCM_DIGSPERLONG, (n1 < 0) ? SCM_BIGSIGNFLAG : 0, n2);
+    if (!(SCM_NIMP(n2) && SCM_BIGP(n2)))
+      bady: SCM_WTA (SCM_ARG2, n2);
 # endif
-      }
+  intbig: {
+      inum2big zdigs;
+      BIGGIFY_LONG (SCM_INUM (n1), zdigs);
+      return scm_big_xor (BIGGIFIED_DIGITS (zdigs), SCM_DIGSPERLONG, 
+			  (n1 < 0) ? SCM_BIGSIGNFLAG : 0, n2);
+    }
   }
 #else
   SCM_ASRTGO(INUMP(n1), badx);
@@ -940,18 +941,14 @@
   if SCM_NINUMP(n2) {
 # ifndef SCM_RECKLESS
     if (!(SCM_NIMP(n2) && SCM_BIGP(n2)))
-    bady: SCM_WTA(SCM_ARG2, n2);
+      bady: SCM_WTA(SCM_ARG2, n2);
 # endif
   intbig: {
-# ifndef SCM_DIGSTOOBIG
-    long z = scm_pseudolong(SCM_INUM(n1));
-    return scm_big_test((SCM_BIGDIG *)&z, SCM_DIGSPERLONG, (n1 < 0) ? SCM_BIGSIGNFLAG : 0, n2);
-# else
-    SCM_BIGDIG zdigs[SCM_DIGSPERLONG];
-    scm_longdigs(SCM_INUM(n1), zdigs);
-    return scm_big_test(zdigs, SCM_DIGSPERLONG, (n1 < 0) ? SCM_BIGSIGNFLAG : 0, n2);
-# endif
-  }}
+      inum2big zdigs;
+      BIGGIFY_LONG (SCM_INUM (n1), zdigs);
+      return scm_big_test(BIGGIFIED_DIGITS (zdigs), SCM_DIGSPERLONG, 
+			  (n1 < 0) ? SCM_BIGSIGNFLAG : 0, n2);
+    }}
 #else
   SCM_ASRTGO(SCM_INUMP(n1), badx);
   SCM_ASSERT(SCM_INUMP(n2), n2, SCM_ARG2, FUNC_NAME);
@@ -1491,49 +1488,7 @@
   return 0;
 }
 
-#ifndef SCM_DIGSTOOBIG
 
-
-long
-scm_pseudolong (long x)
-{
-  union
-  {
-    long l;
-    SCM_BIGDIG bd[SCM_DIGSPERLONG];
-  }
-  p;
-  scm_sizet i = 0;
-  if (x < 0)
-    x = -x;
-  while (i < SCM_DIGSPERLONG)
-    {
-      p.bd[i++] = SCM_BIGLO (x);
-      x = SCM_BIGDN (x);
-    }
-  /*  p.bd[0] = SCM_BIGLO(x); p.bd[1] = SCM_BIGDN(x); */
-  return p.l;
-}
-
-#else
-
-
-void
-scm_longdigs (long x, SCM_BIGDIG digs[])
-{
-  scm_sizet i = 0;
-  if (x < 0)
-    x = -x;
-  while (i < SCM_DIGSPERLONG)
-    {
-      digs[i++] = SCM_BIGLO (x);
-      x = SCM_BIGDN (x);
-    }
-}
-#endif
-
-
-
 SCM
 scm_addbig (SCM_BIGDIG *x, scm_sizet nx, int xsgn, SCM bigy, int sgny)
 {
@@ -1692,18 +1647,11 @@
       return SCM_MAKINUM (sgn ? -t2 : t2);
     }
   {
-#ifndef SCM_DIGSTOOBIG
-    unsigned long t2 = scm_pseudolong (z);
+    inum2big t2;
+    BIGGIFY_LONG (z, t2);
     return scm_divbigbig (SCM_BDIGITS (x), SCM_NUMDIGS (x),
-			  (SCM_BIGDIG *) & t2, SCM_DIGSPERLONG,
+			  BIGGIFIED_DIGITS (t2), SCM_DIGSPERLONG,
 			  sgn, mode);
-#else
-    SCM_BIGDIG t2[SCM_DIGSPERLONG];
-    scm_longdigs (z, t2);
-    return scm_divbigbig (SCM_BDIGITS (x), SCM_NUMDIGS (x),
-			  t2, SCM_DIGSPERLONG,
-			  sgn, mode);
-#endif
   }
 }
 
@@ -3434,18 +3382,10 @@
 	intbig:
 	  {
 	    long i = SCM_INUM (x);
-#  ifndef SCM_DIGSTOOBIG
-	    long z = scm_pseudolong (i);
-	    return scm_addbig ((SCM_BIGDIG *) & z,
-			       SCM_DIGSPERLONG,
-			       (i < 0) ? SCM_BIGSIGNFLAG : 0,
-			       y, 0);
-#  else  /* SCM_DIGSTOOBIG */
-	    SCM_BIGDIG zdigs[SCM_DIGSPERLONG];
-	    scm_longdigs (i, zdigs);
-	    return scm_addbig (zdigs, SCM_DIGSPERLONG, (i < 0) ? SCM_BIGSIGNFLAG : 0,
-			       y, 0);
-#  endif /* SCM_DIGSTOOBIG */
+	    inum2big zdigs;
+	    BIGGIFY_LONG (i, zdigs);
+	    return scm_addbig (BIGGIFIED_DIGITS (zdigs), SCM_DIGSPERLONG, 
+			       (i < 0) ? SCM_BIGSIGNFLAG : 0, y, 0);
 	  }
 	}
 # endif /* SCM_BIGDIG */
@@ -3586,21 +3526,13 @@
     {
 #ifdef SCM_BIGDIG
       SCM_ASRTGO (SCM_NIMP (y), bady);
-      if (SCM_BIGP (y))
-	{
-	  long i = SCM_INUM (x);
-#ifndef SCM_DIGSTOOBIG
-	  long z = scm_pseudolong (i);
-	  return scm_addbig ((SCM_BIGDIG *) & z, SCM_DIGSPERLONG,
-			     (i < 0) ? SCM_BIGSIGNFLAG : 0,
-			     y, SCM_BIGSIGNFLAG);
-#else
-	  SCM_BIGDIG zdigs[SCM_DIGSPERLONG];
-	  scm_longdigs (i, zdigs);
-	  return scm_addbig (zdigs, SCM_DIGSPERLONG, (i < 0) ? SCM_BIGSIGNFLAG : 0,
-			     y, SCM_BIGSIGNFLAG);
-#endif
-	}
+      if (SCM_BIGP (y)) {
+	long i = SCM_INUM (x);
+	inum2big zdigs;
+	BIGGIFY_LONG (i, zdigs);
+	return scm_addbig (BIGGIFIED_DIGITS (zdigs), SCM_DIGSPERLONG, 
+			   (i < 0) ? SCM_BIGSIGNFLAG : 0, y, SCM_BIGSIGNFLAG);
+      }
       if (!SCM_SLOPPY_INEXACTP (y))
 	{
 	bady:
@@ -3733,18 +3665,11 @@
 	  if (SCM_EQ_P (x, SCM_MAKINUM (1L)))
 	    return y;
 	  {
-#ifndef SCM_DIGSTOOBIG
-	    long z = scm_pseudolong (SCM_INUM (x));
-	    return scm_mulbig ((SCM_BIGDIG *) & z, SCM_DIGSPERLONG,
-			       SCM_BDIGITS (y), SCM_NUMDIGS (y),
-			       SCM_BIGSIGN (y) ? (x > 0) : (x < 0));
-#else
-	    SCM_BIGDIG zdigs[SCM_DIGSPERLONG];
-	    scm_longdigs (SCM_INUM (x), zdigs);
-	    return scm_mulbig (zdigs, SCM_DIGSPERLONG,
+	    inum2big zdigs;
+	    BIGGIFY_LONG (SCM_INUM (x), zdigs);
+	    return scm_mulbig (BIGGIFIED_DIGITS (zdigs), SCM_DIGSPERLONG,
 			       SCM_BDIGITS (y), SCM_NUMDIGS (y),
 			       SCM_BIGSIGN (y) ? (x > 0) : (x < 0));
-#endif
 	  }
 	}
       SCM_ASRTGO (SCM_SLOPPY_INEXACTP (y), bady);
@@ -3767,20 +3692,13 @@
 #ifdef SCM_BIGDIG
       {
 	int sgn = (i < 0) ^ (j < 0);
-#ifndef SCM_DIGSTOOBIG
-	i = scm_pseudolong (i);
-	j = scm_pseudolong (j);
-	return scm_mulbig ((SCM_BIGDIG *) & i, SCM_DIGSPERLONG,
-			   (SCM_BIGDIG *) & j, SCM_DIGSPERLONG, sgn);
-#else /* SCM_DIGSTOOBIG */
-	SCM_BIGDIG idigs[SCM_DIGSPERLONG];
-	SCM_BIGDIG jdigs[SCM_DIGSPERLONG];
-	scm_longdigs (i, idigs);
-	scm_longdigs (j, jdigs);
-	return scm_mulbig (idigs, SCM_DIGSPERLONG,
-			   jdigs, SCM_DIGSPERLONG,
+	inum2big idigs;
+	inum2big jdigs;
+	BIGGIFY_LONG (i, idigs);
+	BIGGIFY_LONG (j, jdigs);
+	return scm_mulbig (BIGGIFIED_DIGITS (idigs), SCM_DIGSPERLONG,
+			   BIGGIFIED_DIGITS (jdigs), SCM_DIGSPERLONG,
 			   sgn);
-#endif
       }
 #else
     return scm_makdbl (((double) i) * ((double) j), 0.0);
@@ -3870,21 +3788,13 @@
 			  ? scm_makdbl (scm_big2dbl (x) / SCM_INUM (y), 0.0)
 			  : scm_normbig (w));
 		}
-#ifndef SCM_DIGSTOOBIG
-	      /*ugh! Does anyone know what this is supposed to do?*/
-	      z = scm_pseudolong (z);
-	      z = SCM_INUM(scm_divbigbig (SCM_BDIGITS (x), SCM_NUMDIGS (x),
-                                          (SCM_BIGDIG *) & z, SCM_DIGSPERLONG,
-                                          SCM_BIGSIGN (x) ? (y > 0) : (y < 0), 3));
-#else
 	      {
-		SCM_BIGDIG zdigs[SCM_DIGSPERLONG];
-		scm_longdigs (z, zdigs);
+		inum2big zdigs;
+		BIGGIFY_LONG (z, zdigs);
 		z = scm_divbigbig (SCM_BDIGITS (x), SCM_NUMDIGS (x),
-				   zdigs, SCM_DIGSPERLONG,
+				   BIGGIFIED_DIGITS (zdigs), SCM_DIGSPERLONG,
 				   SCM_BIGSIGN (x) ? (y > 0) : (y < 0), 3);
 	      }
-#endif
 	      return z ? SCM_PACK (z) : scm_makdbl (scm_big2dbl (x) / SCM_INUM (y), 0.0);
 	    }
 	  SCM_ASRTGO (SCM_NIMP (y), bady);
Index: numbers.h
===================================================================
RCS file: /cvs/guile/guile/guile-core/libguile/numbers.h,v
retrieving revision 1.32
diff -u -r1.32 numbers.h
--- numbers.h	2000/04/04 12:13:41	1.32
+++ numbers.h	2000/04/14 08:52:38
@@ -205,12 +205,9 @@
 
 /* Define SCM_BIGDIG to an integer type whose size is smaller than long if
  * you want bignums.  SCM_BIGRAD is one greater than the biggest SCM_BIGDIG. 
- *
- * Define SCM_DIGSTOOBIG if the digits equivalent to a long won't fit in a long. 
  */
 #ifdef BIGNUMS
 # ifdef _UNICOS
-#  define SCM_DIGSTOOBIG
 #  if (1L << 31) <= SCM_USHRT_MAX
 #   define SCM_BIGDIG unsigned  short
 #  else
@@ -319,8 +316,6 @@
 extern SCM scm_2ulong2big (unsigned long * np);
 extern SCM scm_ulong2big (unsigned long n);
 extern int scm_bigcomp (SCM x, SCM y);
-extern long scm_pseudolong (long x);
-extern void scm_longdigs (long x, SCM_BIGDIG digs[]);
 extern SCM scm_addbig (SCM_BIGDIG *x, scm_sizet nx, int xsgn, SCM bigy, int sgny);
 extern SCM scm_mulbig (SCM_BIGDIG *x, scm_sizet nx, SCM_BIGDIG *y, scm_sizet ny, int sgn);
 extern unsigned int scm_divbigdig (SCM_BIGDIG *ds, scm_sizet h, SCM_BIGDIG div);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]