This is the mail archive of the
guile@sourceware.cygnus.com
mailing list for the Guile project.
Re: scm_pseudolong vs. scm_longdigs
- To: Guile Mailing List <guile at sourceware dot cygnus dot com>
- Subject: Re: scm_pseudolong vs. scm_longdigs
- From: Dirk Herrmann <dirk at ida dot ing dot tu-bs dot de>
- Date: Fri, 14 Apr 2000 10:56:03 +0200 (MEST)
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);