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]

Bugs in numbers.c (with patch)


Howdy Guile List!

This has puzzled me for several days now.

Before the patch:
(number->integer (- #x1fffffff 1) 16))  ->  1ffffffe
(number->integer (- #x20000000 1) 16))  ->  20000001  ???
(number->integer (- -1 #x1fffffff) 16))  ->  -20000000
(number->integer (- -1 #x20000000) 16))  ->  -1fffffff  ???

After the patch:
(number->integer (- #x1fffffff 1) 16))  ->  1ffffffe
(number->integer (- #x20000000 1) 16))  ->  1fffffff  yes!
(number->integer (- -1 #x1fffffff) 16))  ->  -20000000
(number->integer (- -1 #x20000000) 16))  ->  -20000001  yes!

SCM is now (void *).  So it is unsigned.  So (x < 0) will *never*
return true.  The compiler will probably just optimize away the tests.
I would think it would be a good idea to go over all the code and
check for places where a raw SCM value is compared < 0.

The patch to numbers.h I'm not sure about, but I think it's right.

-Dale

Index: libguile/numbers.c
===================================================================
RCS file: /cvs/guile/guile/guile-core/libguile/numbers.c,v
retrieving revision 1.74
diff -u -r1.74 numbers.c
--- numbers.c	2000/03/20 18:14:06	1.74
+++ numbers.c	2000/03/22 16:39:27
@@ -3430,12 +3430,12 @@
 	    long z = scm_pseudolong (SCM_INUM (x));
 	    return scm_addbig ((SCM_BIGDIG *) & z,
 			       SCM_DIGSPERLONG,
-			       (x < 0) ? SCM_BIGSIGNFLAG : 0,
+			       (SCM_UNPACK(x) < 0) ? SCM_BIGSIGNFLAG : 0,
 			       y, 0);
 #  else  /* SCM_DIGSTOOBIG */
 	    SCM_BIGDIG zdigs[SCM_DIGSPERLONG];
 	    scm_longdigs (SCM_INUM (x), zdigs);
-	    return scm_addbig (zdigs, SCM_DIGSPERLONG, (x < 0) ? SCM_BIGSIGNFLAG : 0,
+	    return scm_addbig (zdigs, SCM_DIGSPERLONG, (SCM_UNPACK(x) < 0) ? SCM_BIGSIGNFLAG : 0,
 			       y, 0);
 #  endif /* SCM_DIGSTOOBIG */
 	  }
@@ -3583,12 +3583,12 @@
 #ifndef SCM_DIGSTOOBIG
 	  long z = scm_pseudolong (SCM_INUM (x));
 	  return scm_addbig ((SCM_BIGDIG *) & z, SCM_DIGSPERLONG,
-			     (x < 0) ? SCM_BIGSIGNFLAG : 0,
+			     (SCM_UNPACK(x) < 0) ? SCM_BIGSIGNFLAG : 0,
 			     y, SCM_BIGSIGNFLAG);
 #else
 	  SCM_BIGDIG zdigs[SCM_DIGSPERLONG];
 	  scm_longdigs (SCM_INUM (x), zdigs);
-	  return scm_addbig (zdigs, SCM_DIGSPERLONG, (x < 0) ? SCM_BIGSIGNFLAG : 0,
+	  return scm_addbig (zdigs, SCM_DIGSPERLONG, (SCM_UNPACK(x) < 0) ? SCM_BIGSIGNFLAG : 0,
 			     y, SCM_BIGSIGNFLAG);
 #endif
 	}
Index: libguile/numbers.h
===================================================================
RCS file: /cvs/guile/guile/guile-core/libguile/numbers.h,v
retrieving revision 1.30
diff -u -r1.30 numbers.h
--- numbers.h	2000/03/22 10:27:35	1.30
+++ numbers.h	2000/03/22 16:39:29
@@ -263,7 +263,7 @@
   SCM_SETCAR (x, \
 	      scm_tc16_big \
 	      | ((sign) ? SCM_BIGSIGNFLAG : 0) \
-	      | (((v) + 0L) << 17)) \
+	      | (((v) + 0L) << SCM_BIGSIZEFIELD)) \

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