598 |
598 |
599 ! ! |
599 ! ! |
600 |
600 |
601 !Number methodsFor:'truncation and rounding'! |
601 !Number methodsFor:'truncation and rounding'! |
602 |
602 |
|
603 detentBy: detent atMultiplesOf: grid snap: snap |
|
604 "Map all values that are within detent/2 of any multiple of grid |
|
605 to that multiple. |
|
606 Otherwise, if snap is true, return self, meaning that the values |
|
607 in the dead zone will never be returned. |
|
608 If snap is false, then expand the range between dead zones |
|
609 so that it covers the range between multiples of the grid, |
|
610 and scale the value by that factor." |
|
611 |
|
612 | r1 r2 | |
|
613 |
|
614 r1 := self roundTo: grid. "Nearest multiple of grid" |
|
615 (self roundTo: detent) = r1 ifTrue: [^ r1]. "Snap to that multiple..." |
|
616 snap ifTrue: [^ self]. "...or return self" |
|
617 |
|
618 r2 := self < r1 "Nearest end of dead zone" |
|
619 ifTrue: [r1 - (detent asFloat/2)] |
|
620 ifFalse: [r1 + (detent asFloat/2)]. |
|
621 |
|
622 "Scale values between dead zones to fill range between multiples" |
|
623 ^ r1 + ((self - r2) * grid asFloat / (grid - detent)) |
|
624 |
|
625 " |
|
626 (170 to: 190 by: 2) collect: [:a | a detentBy: 10 atMultiplesOf: 90 snap: true] |
|
627 (170 to: 190 by: 2) collect: [:a | a detentBy: 10 atMultiplesOf: 90 snap: false] |
|
628 (3.9 to: 4.1 by: 0.02) collect: [:a | a detentBy: 0.1 atMultiplesOf: 1.0 snap: true] |
|
629 (-3.9 to: -4.1 by: -0.02) collect: [:a | a detentBy: 0.1 atMultiplesOf: 1.0 snap: false] |
|
630 " |
|
631 ! |
|
632 |
603 fractionPart |
633 fractionPart |
604 "return a float with value from digits after the decimal point. |
634 "return a float with value from digits after the decimal point. |
605 (i.e. the receiver minus its truncated value)" |
635 (i.e. the receiver minus its truncated value)" |
606 |
636 |
607 ^ self - self truncated asFloat |
637 ^ self - self truncated asFloat |