[Bug] When (1063751680 < 1063751679) is true!

Peter William Lount peter at ActiveInfo.CA
Sun Feb 1 01:00:41 UTC 2004


Hi,

I'm not quite sure what this bug is but it sure drove me crazy for hours
trying to find it. Of course I assumed that

(1063751680 < 1063751679)

 would be false, but I found a case where it's true! Yikes!

Ok here is a code fragment which reproduces the problem. The start and end
variables that I'm constructing are ip addresses or 32 bit integers.

     | aStart anEnd aRange anIndex aList |
     "Specify the temporary variables so you can see them in the debugger"
     aStart := Integer byte1: 0 byte2: 140 byte3: 103 byte4: 63.
     anEnd := Integer byte1: 255 byte2: 143 byte3: 103 byte4: 63.
    "At this point the above produces two LargePositiveIntegers"

     aRange := anEnd - aStart + 1. "produces an SmallInteger, 1024".

     anIndex := aStart.
    "anIndex starts out as a LargePositiveInteger"

     aList := OrderedCollection new.
self halt.
     [anIndex < anEnd] whileTrue: [
          aList add: anIndex.
          anIndex := anIndex + aRange.
          "anIndex just became a SmallInteger, just in time for loop to
fail!"
     ].
     aList size

The above produces aList of size 9757 when it should produce 1. It is also
the case when 1063751680 < 1063751679 is true!


Here is the code working. Well I simply solve the avoided the problem by
converting or normalizing the LargePositiveIntegers into SmallIntegers.

    | aStart anEnd aRange anIndex aList |
    aStart := (Integer byte1: 0 byte2: 140 byte3: 103 byte4: 63) normalize.
    anEnd := (Integer byte1: 255 byte2: 143 byte3: 103 byte4: 63) normalize.
    aRange := anEnd - aStart + 1.

    anIndex := aStart.
    aList := OrderedCollection new.
    [anIndex < anEnd] whileTrue: [
        aList add: anIndex.
        anIndex := anIndex + aRange.
     ].
     aList size

This produces aList size of 1.

What's going on? Well it seems that the second time through the loop test,
anIndex is a SmallInteger while the first time through it's a
LargePositiveInteger. SmallInteger's "<" is having an argument that is a
LargePositiveInteger (the variable "anEnd"). Of course this shouldn't be
happening as the method comment for "<" says. However, it seems appropriate
for SmallInteger to use it's less than method, "<", with it's parameter,
another number, so what's up? It seems the problem is with SmallInteger's
"<" method not liking a LargePositiveInteger. NO, the following line proves
that wrong or not entirely accurate.

1063751680 < 10637516801063751680

produces true from a SmallInteger and a LargePositiveInteger as a parameter.

It must be something to do with the block "[anIndex < anEnd]" and the fact
that the variable "anInteger" is a LargePositiveInteger the first time
through the loop and the next time it's a small integer. Or something like
that. Got any ideas?

All the best,

Peter William Lount, Smalltalk.org guy
peter at smalltalk.org
peter at activeinfo.ca





More information about the Squeak-dev mailing list