'From Squeak3.10beta of 22 July 2007 [latest update: #7159] on 8 July 2008 at 2:27:36 am'!
"Change Set: SmallInteger-highBit-lowBit-SpeedUp-M7113-nice
Date: 8 July 2008
Author: nice
This change set will speed up SmallInteger highBit and lowBit"!
!SmallInteger methodsFor: 'bit manipulation' stamp: 'nice 7/8/2008 01:40'!
lowBit
" Answer the index of the low order one bit.
2r00101000 lowBit (Answers: 4)
2r-00101000 lowBit (Answers: 4)
First we skip bits in groups of 4, then single bits.
While not optimal, this is a good tradeoff; long
integer #lowBit always invokes us with bytes."
| n result last4 |
n := self.
n = 0 ifTrue: [ ^ 0 ].
result := 0.
[(last4 := n bitAnd: 16rF) = 0]
whileTrue: [
result := result + 4.
n := n bitShift: -4 ].
"The low bits table can be obtained with:
(1 to: 4) inject: #(1) into: [:lowBits :rank | (lowBits copy at: 1 put: lowBits first + 1; yourself) , lowBits]."
^result + ( #(5 1 2 1 3 1 2 1 4 1 2 1 3 1 2 1) at: (last4)+1)! !
!SmallInteger methodsFor: 'private' stamp: 'nice 7/8/2008 01:15'!
highBitOfPositiveReceiver
| shifted bitNo |
"Answer the index of the high order bit of the receiver, or zero if the
receiver is zero. Receiver has to be positive!!"
shifted := self.
bitNo := 0.
[shifted < 65536]
whileFalse:
[shifted := shifted bitShift: -16.
bitNo := bitNo + 16].
shifted < 256
ifFalse:
[shifted := shifted bitShift: -8.
bitNo := bitNo + 8].
shifted < 16
ifFalse:
[shifted := shifted bitShift: -4.
bitNo := bitNo + 4].
"The high bits table can be obtained with:
(1 to: 4) inject: #(0) into: [:highBits :rank | highBits , (highBits collect: [:e | rank])]."
^bitNo + ( #(0 1 2 2 3 3 3 3 4 4 4 4 4 4 4 4) at: shifted+1)! !