Nicolas Cellier uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-nice.926.mcz ==================== Summary ==================== Name: Collections-nice.926 Author: nice Time: 3 March 2021, 10:46:01.17162 am UUID: bb5d2ec0-d044-c54f-9e8a-5442626c7573 Ancestors: Collections-nice.925 Fix LimitedPrecisionInterval>>collect: it should avoid accumulating increments which also accumulates rounding errors and make collect: behavior diverge from do:. Rather than modifying Interval>>collect:, implement the specific inexact arithmetic handling in specific subclass. Do the same with do: and reverseDo:. This enables restoring the legacy Interval enumerations which perform only one operation per loop instead of two. Do not check rangeIncludes: in indexOf:startingAt:. This is useless foe exact Interval, and now redundant for LimitedPrecisionInterval thanks to more carefull implementation of #size. =============== Diff against Collections-nice.925 =============== Item was changed: ----- Method: Interval>>do: (in category 'enumerating') ----- + do: aBlock + + | aValue | + aValue := start. + step < 0 + ifTrue: [[stop <= aValue] + whileTrue: + [aBlock value: aValue. + aValue := aValue + step]] + ifFalse: [[stop >= aValue] + whileTrue: + [aBlock value: aValue. + aValue := aValue + step]]! - do: aBlock - "Evaluate aBlock for each value of the interval. - Implementation note: instead of repeatedly incrementing the value - aValue := aValue + step. - until stop is reached, - We prefer to recompute value from start - aValue := start + (index * step). - This is better for floating points accuracy, while not degrading Integer and Fraction speed too much. - Moreover, this is consistent with methods #at: and #size" - - | aValue index size | - index := 0. - size := self size. - [index < size] - whileTrue: [aValue := start + (index * step). - index := index + 1. - aBlock value: aValue]! Item was changed: ----- Method: Interval>>indexOf:startingAt: (in category 'accessing') ----- indexOf: anElement startingAt: startIndex "startIndex is an positive integer, the collection index where the search is started." | index | - (self rangeIncludes: anElement) ifFalse: [ ^0 ]. index := (anElement - start / step) rounded + 1. (index between: startIndex and: self size) ifFalse: [ ^0 ]. (self at: index) = anElement ifFalse: [ ^0 ]. ^index! Item was changed: ----- Method: Interval>>reverseDo: (in category 'enumerating') ----- reverseDo: aBlock + "Evaluate aBlock for each element of my interval, in reverse order." + | aValue | + aValue := self last. + step < 0 + ifTrue: [[start >= aValue] + whileTrue: [aBlock value: aValue. + aValue := aValue - step]] + ifFalse: [[start <= aValue] + whileTrue: [aBlock value: aValue. + aValue := aValue - step]]! - "Evaluate aBlock for each element of my interval, in reverse order. - Implementation notes: see do: for an explanation on loop detail" - - | aValue index | - index := self size. - [index > 0] - whileTrue: [ - index := index - 1. - aValue := start + (index * step). - aBlock value: aValue]! Item was added: + ----- Method: LimitedPrecisionInterval>>collect: (in category 'enumerating') ----- + collect: aBlock + "Evaluate aBlock with each of the receiver's elements as the argument. + Collect the resulting values into a collection like the receiver. Answer + the new collection. + Implementation notes: see do: for an explanation on loop detail" + | result | + result := self species new: self size. + 1 to: result size do: + [:i | + "(self at: i) is inlined here to avoid repeated bound checking" + result at: i put: i - 1 * step + start]. + ^ result! Item was added: + ----- Method: LimitedPrecisionInterval>>do: (in category 'enumerating') ----- + do: aBlock + "Evaluate aBlock for each value of the interval. + Implementation note: instead of repeatedly incrementing the value + aValue := aValue + step. + until stop is reached, + We prefer to recompute value from start + aValue := start + (index * step). + This is better for floating points accuracy, while not degrading Integer and Fraction speed too much. + Moreover, this is consistent with methods #at: and #size" + + | aValue index size | + index := 0. + size := self size. + [index < size] + whileTrue: [aValue := start + (index * step). + index := index + 1. + aBlock value: aValue]! Item was added: + ----- Method: LimitedPrecisionInterval>>reverseDo: (in category 'enumerating') ----- + reverseDo: aBlock + "Evaluate aBlock for each element of my interval, in reverse order. + Implementation notes: see do: for an explanation on loop detail" + + | aValue index | + index := self size. + [index > 0] + whileTrue: [ + index := index - 1. + aValue := start + (index * step). + aBlock value: aValue]! |
Free forum by Nabble | Edit this page |