[comp.lang.scheme.c] Apparent bug with "*" for range 0xffc0-0xffff

mckenney@RPI.EDU (Bruce McKenney) (10/12/89)

   We have encountered an apparent bug in C-Scheme when attempting to
multiply two values which are both in the range [65472..65535], which,
for all you bit-twiddlers out there, is [0x0ffc0-0xffff]. A sample:

   1 ]=> (* 65535 65535)
   
   #[SEQUENCE -#x1FFFF]
 
The value after "SEQUENCE" is evidently a function of the input values,
though it's not immediately obvious what that function might be.
   This same behaviour has been observed in the Sun-3, Sun-4, and MTS
(IBM 370) versions. A quick check with the debugger indicates that
neither multiply_signed_bignum() nor multiply_unsigned_bignum() is 
being called. I'm currently checking calls to Prim_Multiply, but 
that's a bit more of a drawn-out process.
    We are running:
Release 6.1.1
Microcode 10.2
Runtime 13.91
SF 3.13

    Has anyone else observed this? Any suggestions where to look?

    Bruce McKenney
    mckenney@itsgw.rpi.edu
    Bruce_McKenney@mts.rpi.edu
    userarkc@rpitsmts.bitnet
 
PS: Any responses are appreciated, but "fixed in Release [N+1]" would be
    less useful than "modify line NNN of file XXX.c to say...", or
    even "it sounds like Prim_Multiply is maybe goofing". We have
    a classful of students who are apparently very attached to this
    range of numbers :-), resulting in an (understandably) irritated 
    professor, i.e. a fix is needed "yesterday".

jinx@ZURICH.AI.MIT.EDU (Guillermo J. Rozas) (10/13/89)

       We have encountered an apparent bug in C-Scheme when attempting to
    multiply two values which are both in the range [65472..65535], which,
    for all you bit-twiddlers out there, is [0x0ffc0-0xffff]. A sample:

       1 ]=> (* 65535 65535)

       #[SEQUENCE -#x1FFFF]

The simplest patch is to modify procedure Mul (in microcode/mul.c) in
the following way:

replace the lines

  if (Lo_C > FIXNUM_SIGN_BIT)
    return NIL;

by

  if ((Lo_C > FIXNUM_SIGN_BIT) || (Lo_C < 0))
    return NIL;

The problem is that the various Hi and Lo have been declared as long,
rather than unsigned long, thus arithmetic is signed.  Declaring them
as unsigned should fix the problem too, but unfortunately some C
compilers ignore the unsigned declaration, and you might still have
a problem.  

I've only tried this patch on 68K HP machines, but it should work on
Suns and others.