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@flinders.edu.au] Sent: Friday, July 30, 1999 2:16 AM To: squeak@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@pacbell.net To: Randal L. Schwartz merlyn@stonehenge.com; squeak@cs.uiuc.edu squeak@cs.uiuc.edu Date: Friday, July 30, 1999 3:24 PM Subject: re: [bug] my first squeak bugfix - Interval>>includes:
** Original Sender: merlyn@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
squeak-dev@lists.squeakfoundation.org