[bug] my first squeak bugfix - Interval>>includes:

Jarvis, Robert P. Jarvisb at timken.com
Fri Jul 30 12:26:13 UTC 1999


It looks like the examples which you expect to evaluate to true are being
affected by floating point roundoff errors.  In particular

	(((1.3 to: 2.2 by: 0.3) collect: [:i | i]) at: 3) = 1.9

evaluates to false (although ((1.3 to: 2.2 by: 0.3) at: 3) = 1.9 evaluates
to true :-).  If you evaluate

	(((1.3 to: 2.2 by: 0.3) collect: [:i | i]) at: 3) - 1.9

you get a result of 2.220446049250313e-16, so it looks like some roundoff
errors are definitely creeping in.  The bottom line is that you can't count
on comparing two floating point values, at least one of which is a
non-literal value, and expect them to be equal no matter how minor the
computations involving them have been.

The desired results can be obtained if by using Fractions instead of Floats.
Try evaluating

	(13/10 to: 22/10 by: 3/10) includes: 19/10
	(1 to: 5 by: 2/10) includes: 1.2
	(1 to: 5 by: 3/10) includes: 1.3

which are equivalent to your expressions, but use Fractions in the
appropriate places.  Granted, calculations using Fractions are likely to be
slower than using Floats, which may be a consideration; however, getting the
wrong answer quickly is no great blessing.

I hope this helps.

Bob Jarvis
The Timken Company

> -----Original Message-----
> From:	Peter Smet [SMTP:peter.smet at flinders.edu.au]
> Sent:	Friday, July 30, 1999 2:16 AM
> To:	squeak at cs.uiuc.edu
> Subject:	Re: [bug] my first squeak bugfix - Interval>>includes:
> 
> Alan,
> 
> I was having a look at a similar fix when you posted your code.
> I think it may not always work due to the nature of \\ and floating
> point precision/rounding. Here are some anomalies:
> (1 to: 5 by: 1) includes: 1.4           -- is true, but should be false
> (1.3 to: 2.2 by: 0.3) includes: 1.9  -- is false but should be true
>  (1 to: 5 by: 0.2) includes: 1.2
> (1 to: 5 by: 0.3) includes: 1.3
> both (incorrectly) evaluate to false...
> 
> Peter
> 
> 
> 
> -----Original Message-----
> From: Alan Lovejoy <sourcery at pacbell.net>
> To: Randal L. Schwartz <merlyn at stonehenge.com>; squeak at cs.uiuc.edu
> <squeak at cs.uiuc.edu>
> Date: Friday, July 30, 1999 3:24 PM
> Subject: re: [bug] my first squeak bugfix - Interval>>includes:
> 
> 
> >> ** Original Sender: merlyn at stonehenge.com (Randal L. Schwartz)
> >>
> >> Interval>>includes: fails if the increment is not 1.  Here's code that
> works:
> >>
> >> includes: aNumber
> >>   ^self increment = 1
> >>     ifTrue: [aNumber between: self first and: self last]
> >>     ifFalse: [super includes: aNumber] "fall back to enumerate items"
> >>
> >
> >Oh dear.  The ParcPlace code for Interval>includes: has worked since I
> first
> >started using it, way back in 1986.  So I was shocked to see the
> following
> code
> >in my Squeak image:
> >
> >Interval>includes: aNumber
> > ^ aNumber between: self first and: self last
> >
> >I guess this reinforces for me yet again that I should not assume that
> >things that have always been working correctly in the ParcPlace
> >image line are also good in Squeak (in spite of the fact that they both
> >ultimately come from Xerox PARC stock).
> >
> >As for the fix above, it will work, but I would like to offer an
> alternative:
> >
> >Interval>includes: aNumber
> > ^ (aNumber between: self first and: self last)
> > and: [self increment = 1
> > ifTrue: [true]
> > ifFalse: [aNumber - self first \\ self increment = 0]]
> >
> >Kudos to Randy for finding this!
> >
> >--Alan
> >





More information about the Squeak-dev mailing list