Integer.st
changeset 24166 0e0a1d3daee2
parent 24153 88feac51cfbb
child 24167 0dc1e390b3e0
--- a/Integer.st	Sun May 26 12:56:06 2019 +0200
+++ b/Integer.st	Mon May 27 08:42:50 2019 +0200
@@ -2459,6 +2459,39 @@
 
 !Integer methodsFor:'bit operators - indexed'!
 
+anyBitOfMagnitudeFrom:startBitIndex to:stopBitIndexArg 
+    "Tests for any magnitude bits in the interval from start to stopArg."
+
+    | magnitude firstDigitIx lastDigitIx rightShift leftShift stopBitIndex |
+
+    "/ <primitive: 'primAnyBitFromTo' module:'LargeIntegers'>
+
+    startBitIndex < 1 | (stopBitIndexArg < 1) ifTrue: [^ self error: 'out of range'].
+    magnitude := self abs.
+    stopBitIndex := stopBitIndexArg min: magnitude highBit.
+    startBitIndex > stopBitIndex ifTrue: [^ false].
+
+    firstDigitIx := (startBitIndex - 1) // 8 + 1.
+    lastDigitIx := (stopBitIndex - 1) // 8 + 1.
+    rightShift := ((startBitIndex - 1) \\ 8) negated.
+    leftShift := 7 - ((stopBitIndex - 1) \\ 8).
+    firstDigitIx = lastDigitIx ifTrue: [
+        | digit mask | 
+        mask := (255 bitShift: rightShift negated)
+                                bitAnd: (255 bitShift: leftShift negated).
+        digit := magnitude digitAt: firstDigitIx.
+        ^ (digit bitAnd: mask) ~= 0
+    ].
+    ((magnitude digitAt: firstDigitIx) bitShift: rightShift) ~= 0 ifTrue: [^ true].
+    firstDigitIx + 1 to: lastDigitIx - 1 do: [:ix | 
+        (magnitude digitAt: ix) ~= 0 ifTrue: [^ true]
+    ].
+    (((magnitude digitAt: lastDigitIx) bitShift: leftShift) bitAnd: 255) ~= 0 ifTrue: [^ true].
+    ^ false
+
+    "Created: / 27-05-2019 / 08:37:08 / Claus Gittinger"
+!
+
 bitAt:index
     "return the value of the index's bit (index starts at 1) as 0 or 1.
      Notice: the result of bitAt: on negative receivers is not