[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" <squeakdev 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.0e10]
> > 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.0e10
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 nonzero 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 Squeakdev
mailing list
