diff options
-rw-r--r-- | libguile/ChangeLog | 5 | ||||
-rw-r--r-- | libguile/numbers.c | 108 |
2 files changed, 63 insertions, 50 deletions
diff --git a/libguile/ChangeLog b/libguile/ChangeLog index 32f20d98c..e487e3bc7 100644 --- a/libguile/ChangeLog +++ b/libguile/ChangeLog @@ -1,3 +1,8 @@ +2000-05-16 Dirk Herrmann <D.Herrmann@tu-bs.de> + + * numbers.c (scm_logcount, scm_integer_length): Reordered + dispatch sequence. + 2000-05-15 Gary Houston <ghouston@arglist.com> * stime.c (scm_strftime): don't reset TZ if zone is an empty diff --git a/libguile/numbers.c b/libguile/numbers.c index 3fca97863..c21b9caf3 100644 --- a/libguile/numbers.c +++ b/libguile/numbers.c @@ -1180,7 +1180,7 @@ SCM_DEFINE (scm_ash, "ash", 2, 0, 0, } #undef FUNC_NAME -/* GJB:FIXME: do not use SCMs as integers! */ + SCM_DEFINE (scm_bit_extract, "bit-extract", 3, 0, 0, (SCM n, SCM start, SCM end), "Returns the integer composed of the @var{start} (inclusive) through\n" @@ -1214,6 +1214,7 @@ SCM_DEFINE (scm_bit_extract, "bit-extract", 3, 0, 0, } #undef FUNC_NAME + static const char scm_logtab[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; @@ -1235,30 +1236,35 @@ SCM_DEFINE (scm_logcount, "logcount", 1, 0, 0, "@end lisp") #define FUNC_NAME s_scm_logcount { - register unsigned long c = 0; - register long nn; -#ifdef SCM_BIGDIG - if (SCM_NINUMP (n)) - { - scm_sizet i; - SCM_BIGDIG *ds, d; - SCM_VALIDATE_BIGINT (1,n); - if (SCM_BIGSIGN (n)) - return scm_logcount (scm_difference (SCM_MAKINUM (-1L), n)); - ds = SCM_BDIGITS (n); - for (i = SCM_NUMDIGS (n); i--;) - for (d = ds[i]; d; d >>= 4) + if (SCM_INUMP (n)) { + unsigned long int c = 0; + long int nn = SCM_INUM (n); + if (nn < 0) { + nn = -1 - nn; + }; + while (nn) { + c += scm_logtab[15 & nn]; + nn >>= 4; + }; + return SCM_MAKINUM (c); + } else if (SCM_BIGP (n)) { + if (SCM_BIGSIGN (n)) { + return scm_logcount (scm_difference (SCM_MAKINUM (-1L), n)); + } else { + unsigned long int c = 0; + scm_sizet i = SCM_NUMDIGS (n); + SCM_BIGDIG * ds = SCM_BDIGITS (n); + while (i--) { + SCM_BIGDIG d; + for (d = ds[i]; d; d >>= 4) { c += scm_logtab[15 & d]; + } + } return SCM_MAKINUM (c); } -#else - SCM_VALIDATE_INUM (1,n); -#endif - if ((nn = SCM_INUM (n)) < 0) - nn = -1 - nn; - for (; nn; nn >>= 4) - c += scm_logtab[15 & nn]; - return SCM_MAKINUM (c); + } else { + SCM_WRONG_TYPE_ARG (SCM_ARG1, n); + } } #undef FUNC_NAME @@ -1281,36 +1287,38 @@ SCM_DEFINE (scm_integer_length, "integer-length", 1, 0, 0, "@end lisp") #define FUNC_NAME s_scm_integer_length { - register unsigned long c = 0; - register long nn; - unsigned int l = 4; -#ifdef SCM_BIGDIG - if (SCM_NINUMP (n)) - { - SCM_BIGDIG *ds, d; - SCM_VALIDATE_BIGINT (1,n); - if (SCM_BIGSIGN (n)) - return scm_integer_length (scm_difference (SCM_MAKINUM (-1L), n)); - ds = SCM_BDIGITS (n); - d = ds[c = SCM_NUMDIGS (n) - 1]; - for (c *= SCM_BITSPERDIG; d; d >>= 4) - { - c += 4; - l = scm_ilentab[15 & d]; - } - return SCM_MAKINUM (c - 4 + l); - } -#else - SCM_VALIDATE_INUM (1,n); -#endif - if ((nn = SCM_INUM (n)) < 0) - nn = -1 - nn; - for (; nn; nn >>= 4) - { + if (SCM_INUMP (n)) { + unsigned long int c = 0; + unsigned int l = 4; + long int nn = SCM_INUM (n); + if (nn < 0) { + nn = -1 - nn; + }; + while (nn) { c += 4; - l = scm_ilentab[15 & nn]; + l = scm_ilentab [15 & nn]; + nn >>= 4; + }; + return SCM_MAKINUM (c - 4 + l); + } else if (SCM_BIGP (n)) { + if (SCM_BIGSIGN (n)) { + return scm_integer_length (scm_difference (SCM_MAKINUM (-1L), n)); + } else { + unsigned long int digs = SCM_NUMDIGS (n) - 1; + unsigned long int c = digs * SCM_BITSPERDIG; + unsigned int l = 4; + SCM_BIGDIG * ds = SCM_BDIGITS (n); + SCM_BIGDIG d = ds [digs]; + while (d) { + c += 4; + l = scm_ilentab [15 & d]; + d >>= 4; + }; + return SCM_MAKINUM (c - 4 + l); } - return SCM_MAKINUM (c - 4 + l); + } else { + SCM_WRONG_TYPE_ARG (SCM_ARG1, n); + } } #undef FUNC_NAME |