[BUG][FIX] Interval method includes:

Boris Gaertner Boris.Gaertner at gmx.net
Fri Jun 18 11:51:29 UTC 2004


 "Wolfgang Eder" <edw at generalmagic.at> wrote:
To: "Squeak list" <squeak-dev at lists.squeakfoundation.org>
Sent: Thursday, June 17, 2004 3:54 PM
Subject: Re: [BUG][FIX] Interval method includes:


> Boris Gaertner wrote:
> [snip]
> > I think now that it is perhaps best to write:
> > 
> > valuesInclude: aNumber
> >     | val |
> >  val _ (aNumber - self first)  / self increment.
> >  ^val isFloat
> >    ifTrue: [val fractionPart abs < 1.0e-10]
> >    ifFalse: [val isInteger]
> > 
> > This version uses exact calculation without
> > floats whenever that is possible. It also
> > avois unnecessary computations with
> > fractions.
> [snip]
> 
> Boris,
> how about adding a protocol like #fractionPartIsZero
> or #isFractionPartZero, with implementations
> in Integer, Fraction, and Float?
> Just my 2c.. regards,
> Wolfgang
> 
Yes, you are right. The key point of your argumentation is
that, in Fraction, we can define

fractionPartIsZero
    ^false

because we know that a fraction like 4/2 is automatically
converted into an integer. The definition in Float
is a bit more problematic, 

fractionPartIsZero
  ^self fractionPart abs <1.0e-10


would do for the purpose of the method
Interval>>includes:

The question is whether this is also a suitable definition
for other purposes.

Note that the test for exact zeroness is not appropriate:

(0.0 to: 1000 by: 0.1) inject:  0
    into: [ :sumOfIntegerValues :item |
             item fractionPart isZero
               ifTrue:
                 [Transcript show: item printString; cr.
                   sumOfIntegerValues := sumOfIntegerValues + 1]
              ifFalse: [sumOfIntegerValues]]


answers  2

because 0.1 has no exact binary representation and therefore
almost all interval elements have a non-zero fraction part.

By contrast, the expression

 ((0.0 to: 1000 by: 0.1) select:
    [ :item | item fractionPart isZero]) size


answers 1001  

This is a surprise, but it is not too difficult to find the
reason:
#inject:into:  uses  Interval>>do: to enumerate the
interval elements, but select: does not use 
Interval>>do: for element enumeration.
(The used definition of #select: is that in
SequenceableCollection. SequenceableCollection
uses #at: to access an collection element and
Interval>>at: uses multiplication to compute
the element for a given collection index.)

The use of two different algorithms for element
computation is of course not optimal, but this is
a different problem.

The closer I look to the definition of Interval,
the more I think that a careful code revision is
really desireable.

Greetings,
Boris





More information about the Squeak-dev mailing list