[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Help-smalltalk] Re: [PATCH] Fraction and Integer asFloat: answer neares
[Help-smalltalk] Re: [PATCH] Fraction and Integer asFloat: answer nearest floating point
Sun, 28 Jan 2007 22:45:51 +0100
Thunderbird 18.104.22.168 (X11/20060516)
Paolo Bonzini a écrit :
nicolas cellier wrote:
here are some enhancements that should answer nearest floating point
value when converting LargeInteger and Fraction asFloat.
For LargePositiveInteger, i have two versions, one un-optimized and
one optimized for gst.
Which is the optimized one (the one whose source does not mention
checkIfLowBitGreaterThan: n, or the other)?
The optimized one is in file named
'LargePositiveIntegerOptimized.asFloat:.st' and it calls
This last message is most of the optimization.
We just need to know if some trailing bits are truncated or not in order
to do the rounding.
Non optimized version is using bit operations with masks like
traditional Smalltalk patterns (bitShift: and bitAnd:). This is
efficient for SmallIntegers. Unfortunately, in our case this creates a
lot of intermediary LargePositiveInteger objects and is slow.
Optimized version do this without creating any new LargePositiveInteger,
just iterating on bits with bitAt: test, which is further accelerated by
testing bytes with digitAt: tests when number of bits > 8 (and would be
further optimized in a primitive with 16, 32 or 64 bits by 64 bits
Also, non zero bit search is stopped as soon as a non zero bit is found.
I am quite sure that a more general message named #lowBit would do
almost as well and could be used in other algorithms.
"answer the index of least significant non zero bit.
answer 0 if receiver is zero.
LSB is indexed 1."
1 to: self size do: [:i | | lowBit |
lowBit := (self digitAt: i) lowBit.
lowBit = 0 ifFalse: [(î-1)*8 + lowBit]].
"same as above.
Note: there are faster implementations to be found for sure"
| shifted lowBit |
self = 0 ifTrue: [^0].
self < 0 ifTrue: [self error: 'i do not know how to handle this
one... and i do not much like negative integer highBit implementation
shifted := self.
lowBit := 1.
[(shifted bitAnd: 1) = 0] whileTrue:
[shifted := shifted bitShift: -1.
lowBit := lowBit+1}.