guile-cvs
[Top][All Lists]
Advanced

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

guile/guile-core/libguile numbers.c num2integra...


From: Marius Vollmer
Subject: guile/guile-core/libguile numbers.c num2integra...
Date: Sun, 11 Nov 2001 20:12:37 -0500

CVSROOT:        /cvs
Module name:    guile
Changes by:     Marius Vollmer <address@hidden> 01/11/11 20:12:37

Modified files:
        guile-core/libguile: numbers.c num2integral.i.c 

Log message:
        * numbers.c: Document macros to define when including
        num2integral.i.c.  MAX_VALUE and MIN_VALU are no longer used, we
        now rely on SIZEOF_ macros that have been figured out at
        configure time.
        
        * num2integral.i.c: Adapt to new interface.
        (NUM2INTEGRAL): Test whether a fixnum can be represented in the
        target type by casting it and checking whether it is still the
        same.  Do not try to handle bignums for integral types that are
        smaller than fixnums.  When handling bignums, collect the
        magnituse first into a unsigned type, and correctly check for
        overflow.
        (INTEGRAL2BIG): Do not use MIN_VALUE explicitely by observing that
        only -MIN_VALUE can still be negative of all negative numbers (in
        twos-complement).

CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/guile/guile-core/libguile/numbers.c.diff?cvsroot=OldCVS&tr1=1.150&tr2=1.151&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/guile/guile-core/libguile/num2integral.i.c.diff?cvsroot=OldCVS&tr1=1.12&tr2=1.13&r1=text&r2=text

Patches:
Index: guile/guile-core/libguile/num2integral.i.c
diff -u guile/guile-core/libguile/num2integral.i.c:1.12 
guile/guile-core/libguile/num2integral.i.c:1.13
--- guile/guile-core/libguile/num2integral.i.c:1.12     Sun Nov  4 10:52:29 2001
+++ guile/guile-core/libguile/num2integral.i.c  Sun Nov 11 20:12:37 2001
@@ -1,5 +1,19 @@
 /* this file is #include'd (many times) by numbers.c */
 
+#ifndef UNSIGNED_ITYPE
+#ifdef UNSIGNED
+#define UNSIGNED_ITYPE ITYPE
+#else
+#define UNSIGNED_ITYPE unsigned ITYPE
+#endif
+#endif
+
+#define UNSIGNED_ITYPE_MAX (~((UNSIGNED_ITYPE)0))
+
+#ifndef SIZEOF_ITYPE
+#define SIZEOF_ITYPE (2*SIZEOF_SCM_T_BITS)
+#endif
+
 ITYPE
 NUM2INTEGRAL (SCM num, unsigned long int pos, const char *s_caller)
 {
@@ -19,11 +33,7 @@
         return (ITYPE) n;
       else
         { /* an inum can be out of range, so check */
-          if (n > (scm_t_signed_bits)MAX_VALUE
-#ifndef UNSIGNED
-              || n < (scm_t_signed_bits)MIN_VALUE
-#endif
-              )
+         if (((ITYPE)n) != n)
             scm_out_of_range (s_caller, num);
           else
             return (ITYPE) n;
@@ -31,8 +41,9 @@
     }
   else if (SCM_BIGP (num))
     { /* bignum */
-    
-      ITYPE res = 0;
+#if SIZEOF_ITYPE >= SIZEOF_SCM_T_BITS
+      
+      UNSIGNED_ITYPE pos_res = 0;
       size_t l;
 
 #ifdef UNSIGNED
@@ -42,22 +53,17 @@
 
       for (l = SCM_NUMDIGS (num); l--;)
         {
-          ITYPE new = SCM_I_BIGUP (ITYPE, res) + SCM_BDIGITS (num)[l];
-          if (new < res
-#ifndef UNSIGNED
-              && !(new == MIN_VALUE && l == 0)
-#endif
-              )
+         if (pos_res > SCM_BIGDN (UNSIGNED_ITYPE_MAX))
             scm_out_of_range (s_caller, num);
-          res = new;
+         pos_res = SCM_I_BIGUP (ITYPE, pos_res) + SCM_BDIGITS (num)[l];
         }
     
 #ifdef UNSIGNED
-      return res;
+      return pos_res;
 #else
       if (SCM_BIGSIGN (num))
         {
-          res = -res;
+          ITYPE res = -((ITYPE)pos_res);
           if (res <= 0)
             return res;
           else
@@ -65,12 +71,18 @@
         }
       else
         {
+         ITYPE res = (ITYPE)pos_res;
           if (res >= 0)
             return res;
           else
             scm_out_of_range (s_caller, num);
         }
 #endif
+      
+#else /* SIZEOF_ITYPE >= SIZEOF_SCM_T_BITS */
+            scm_out_of_range (s_caller, num);
+#endif
+      
     }
   else
     scm_wrong_type_arg (s_caller, pos, num);
@@ -79,43 +91,22 @@
 SCM
 INTEGRAL2NUM (ITYPE n)
 {
-  /* Determine at compile time whether we need to porferm the FIXABLE
-     test or not.  This is not done to get more optimal code out of
-     the compiler (it can figure this out on its already), but to
-     avoid a spurious warning. 
+  /* If we know the size of the type, determine at compile time
+     whether we need to perform the FIXABLE test or not.  This is not
+     done to get more optimal code out of the compiler (it can figure
+     this out on its own already), but to avoid a spurious warning.
+     If we don't know the size, assume that the test must be done.
   */
 
-#ifdef NEED_CHECK
-#undef NEED_CHECK
-#endif
-
-#ifdef NO_PREPRO_MAGIC
-#define NEED_CHECK
-#else
-#ifdef UNSIGNED
-#if MAX_VALUE>SCM_MOST_POSITIVE_FIXNUM
-#define NEED_CHECK
-#endif
-#else
-#if MIN_VALUE<SCM_MOST_NEGATIVE_FIXNUM || MAX_VALUE>SCM_MOST_POSITIVE_FIXNUM
-#define NEED_CHECK
-#endif
-#endif
-#endif
-
+#if SIZEOF_ITYPE >= SIZEOF_SCM_T_BITS
 #ifndef UNSIGNED
-#ifdef NEED_CHECK
   if (SCM_FIXABLE (n))
-#endif
 #else
-#ifdef NEED_CHECK
   if (SCM_POSFIXABLE (n))
 #endif
 #endif
     return SCM_MAKINUM ((scm_t_signed_bits) n);
 
-#undef NEED_CHECK
-
 #ifdef SCM_BIGDIG
   return INTEGRAL2BIG (n);
 #else
@@ -142,10 +133,17 @@
 #endif
 
 #ifndef UNSIGNED
-  if (n == MIN_VALUE)
-    /* special case */
-    n_digits =
-      (sizeof (ITYPE) + sizeof (SCM_BIGDIG) - 1) / sizeof (SCM_BIGDIG);
+  /* If n is still negative here, it must be the minimum value of the
+     type (assuming twos-complement, but we are tied to that anyway).
+     If this is the case, we can not count the number of digits by
+     right-shifting n until it is zero.
+  */
+  if (n < 0)
+    {
+      /* special case */
+      n_digits = 
+       (sizeof (ITYPE) + sizeof (SCM_BIGDIG) - 1) / sizeof (SCM_BIGDIG);
+    }
   else
 #endif
     {
@@ -175,11 +173,13 @@
 #undef INTEGRAL2NUM
 #undef INTEGRAL2BIG
 #undef NUM2INTEGRAL
+#ifdef UNSIGNED
 #undef UNSIGNED
+#endif
 #undef ITYPE
-#undef MIN_VALUE
-#undef MAX_VALUE
-#undef NO_PREPRO_MAGIC
+#undef SIZEOF_ITYPE
+#undef UNSIGNED_ITYPE
+#undef UNSIGNED_ITYPE_MAX
 
 /*
   Local Variables:
Index: guile/guile-core/libguile/numbers.c
diff -u guile/guile-core/libguile/numbers.c:1.150 
guile/guile-core/libguile/numbers.c:1.151
--- guile/guile-core/libguile/numbers.c:1.150   Wed Nov  7 10:08:45 2001
+++ guile/guile-core/libguile/numbers.c Sun Nov 11 20:12:37 2001
@@ -4258,12 +4258,47 @@
 # endif
 #endif
 
+/* Parameters for creating integer conversion routines.
+
+   Define the following preprocessor macros before including
+   "libguile/num2integral.i.c":
+
+   NUM2INTEGRAL - the name of the function for converting from a
+                  Scheme object to the integral type.  This function
+                  will be defined when including "num2integral.i.c".
+
+   INTEGRAL2NUM - the name of the function for converting from the
+                  integral type to a Scheme object.  This function
+                  will be defined.
+
+   INTEGRAL2BIG - the name of an internal function that createas a
+                  bignum from the integral type.  This function will
+                  be defined.  The name should start with "scm_i_".
+
+   ITYPE        - the name of the integral type.
+
+   UNSIGNED     - Define this when ITYPE is an unsigned type.  Do not
+                  define it otherwise.
+
+   UNSIGNED_ITYPE
+                - the name of the the unsigned variant of the
+                  integral type.  If you don't define this, it defaults
+                  to "unsigned ITYPE" for signed types and simply "ITYPE"
+                  for unsigned ones.
+
+   SIZEOF_ITYPE - an expression giving the size of the integral type in
+                  bytes.  This expression must be computable by the
+                  preprocessor.  If you don't know a value for this,
+                  don't define it.  The purpose of this parameter is
+                  mainly to suppress some warnings.  The generated
+                  code will work correctly without it.
+*/
+
 #define NUM2INTEGRAL scm_num2short
 #define INTEGRAL2NUM scm_short2num
 #define INTEGRAL2BIG scm_i_short2big
 #define ITYPE short
-#define MIN_VALUE SHRT_MIN
-#define MAX_VALUE SHRT_MAX
+#define SIZEOF_ITYPE SIZEOF_SHORT
 #include "libguile/num2integral.i.c"
 
 #define NUM2INTEGRAL scm_num2ushort
@@ -4271,15 +4306,14 @@
 #define INTEGRAL2BIG scm_i_ushort2big
 #define UNSIGNED
 #define ITYPE unsigned short
-#define MAX_VALUE USHRT_MAX
+#define SIZEOF_ITYPE SIZEOF_SHORT
 #include "libguile/num2integral.i.c"
 
 #define NUM2INTEGRAL scm_num2int
 #define INTEGRAL2NUM scm_int2num
 #define INTEGRAL2BIG scm_i_int2big
 #define ITYPE int
-#define MIN_VALUE INT_MIN
-#define MAX_VALUE INT_MAX
+#define SIZEOF_ITYPE SIZEOF_INT
 #include "libguile/num2integral.i.c"
 
 #define NUM2INTEGRAL scm_num2uint
@@ -4287,15 +4321,14 @@
 #define INTEGRAL2BIG scm_i_uint2big
 #define UNSIGNED
 #define ITYPE unsigned int
-#define MAX_VALUE UINT_MAX
+#define SIZEOF_ITYPE SIZEOF_INT
 #include "libguile/num2integral.i.c"
 
 #define NUM2INTEGRAL scm_num2long
 #define INTEGRAL2NUM scm_long2num
 #define INTEGRAL2BIG scm_i_long2big
 #define ITYPE long
-#define MIN_VALUE LONG_MIN
-#define MAX_VALUE LONG_MAX
+#define SIZEOF_ITYPE SIZEOF_LONG
 #include "libguile/num2integral.i.c"
 
 #define NUM2INTEGRAL scm_num2ulong
@@ -4303,40 +4336,23 @@
 #define INTEGRAL2BIG scm_i_ulong2big
 #define UNSIGNED
 #define ITYPE unsigned long
-#define MAX_VALUE ULONG_MAX
+#define SIZEOF_ITYPE SIZEOF_LONG
 #include "libguile/num2integral.i.c"
 
-#ifndef PTRDIFF_MIN
-/* the below is not really guaranteed to work (I think), but probably does: */
-#define PTRDIFF_MIN ((ptrdiff_t) ((ptrdiff_t)1 << (sizeof (ptrdiff_t)*8 - 1)))
-/* this prevents num2integral.c.i from using PTRDIFF_MIN in
-   preprocessor expressions. */
-#define NO_PREPRO_MAGIC
-#endif
-
-#ifndef PTRDIFF_MAX
-#define PTRDIFF_MAX (~ PTRDIFF_MIN)
-#endif
-
 #define NUM2INTEGRAL scm_num2ptrdiff
 #define INTEGRAL2NUM scm_ptrdiff2num
 #define INTEGRAL2BIG scm_i_ptrdiff2big
 #define ITYPE ptrdiff_t
-#define MIN_VALUE PTRDIFF_MIN
-#define MAX_VALUE PTRDIFF_MAX
+#define UNSIGNED_ITYPE size_t
+#define SIZEOF_ITYPE SIZEOF_PTRDIFF_T
 #include "libguile/num2integral.i.c"
 
-#ifndef SIZE_MAX
-#define SIZE_MAX ((size_t) (-1))
-#define NO_PREPRO_MAGIC
-#endif
-
 #define NUM2INTEGRAL scm_num2size
 #define INTEGRAL2NUM scm_size2num
 #define INTEGRAL2BIG scm_i_size2big
 #define UNSIGNED
 #define ITYPE size_t
-#define MAX_VALUE SIZE_MAX
+#define SIZEOF_ITYPE SIZEOF_SIZE_T
 #include "libguile/num2integral.i.c"
 
 #ifdef HAVE_LONG_LONGS
@@ -4349,9 +4365,7 @@
 #define INTEGRAL2NUM scm_long_long2num
 #define INTEGRAL2BIG scm_i_long_long2big
 #define ITYPE long long
-#define MIN_VALUE LLONG_MIN
-#define MAX_VALUE LLONG_MAX
-#define NO_PREPRO_MAGIC
+#define SIZEOF_ITYPE SIZEOF_LONG_LONG
 #include "libguile/num2integral.i.c"
 
 #define NUM2INTEGRAL scm_num2ulong_long
@@ -4359,8 +4373,7 @@
 #define INTEGRAL2BIG scm_i_ulong_long2big
 #define UNSIGNED
 #define ITYPE unsigned long long
-#define MAX_VALUE ULLONG_MAX
-#define NO_PREPRO_MAGIC
+#define SIZEOF_ITYPE SIZEOF_LONG_LONG
 #include "libguile/num2integral.i.c"
 
 #endif /* HAVE_LONG_LONGS */



reply via email to

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