This is the mail archive of the
guile@sourceware.cygnus.com
mailing list for the Guile project.
Bugs in numbers.c (with patch)
- To: guile at sourceware dot cygnus dot com
- Subject: Bugs in numbers.c (with patch)
- From: "Dale P. Smith" <dpsm at en dot com>
- Date: Wed, 22 Mar 2000 11:58:01 -0500
- Organization: Altus Technologies Corporation.
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)) \