Fuhrmanator
Fuhrmanator

Reputation: 12882

How to do a bit mask operation Pharo?

In Pharo, I want to do bit masking on integers, which looks like this in Python:

((b1 & 0x3F) << 4) | (b2 >> 4)

I know that & and | work in Pharo, but I'm pretty sure they're not bit-wise.

Upvotes: 3

Views: 141

Answers (3)

Stephan Eggermont
Stephan Eggermont

Reputation: 15907

If you need to do this a lot, you'll probably don't want to apply this to Integers. They have a special encoding that doesn't allow you to use all 64 bits. Take a look at Collections-Native

Upvotes: 1

EstebanLM
EstebanLM

Reputation: 4357

but you are wrong :)

look at the implementation of &, |, <<, >> in Pharo:

& aNumber
    ^ self bitAnd: aNumber

| anInteger
    ^self bitOr: anInteger

<< shiftAmount
    "left shift"

    shiftAmount < 0 ifTrue: [self error: 'negative arg'].
    ^ self bitShift: shiftAmount

>> shiftAmount
    "right shift"

    shiftAmount < 0 ifTrue: [self error: 'negative arg'].
    ^ self bitShift: 0 - shiftAmount

That basically means that your code will work out of the box except for the translation of hex C style to hex Pharo style:

((b1 & 16r3F) << 4) | (b2 >> 4)

Upvotes: 6

Fuhrmanator
Fuhrmanator

Reputation: 12882

From this gist:

"************************************************************************
 * Bitwise Manipulation:                                                *
 ************************************************************************"
| b x |
x := 2r1111 bitAnd: 2r0100.                                 "and bits"
x := 4r3333 bitAnd: 2r011011011.                            "and with different bases"
x := 2r1111 bitOr: 2r0100.                                  "or bits"
x := 16rFF bitXor: 8r5252.                                  "xor bits mixing bases"
x := 16rFF bitInvert.                                       "invert bits"
x := 2r0100 bitShift: 2.                                    "left shift"
x := 2r0100 bitShift: -2.                                   "right shift"
x := 2r0100 >> 2.                                           "divide by four"
x := 2r0100 << 2.                                           "multiply by four"
x := 2r0100 bitAt: 3.                                       "bit at position (0|1)"
x := 2r0100 highBit.                                        "position of highest bit set"
b := 16rFF allMask: 16r0F.                                  "test if all bits set in mask set in receiver"
b := 16rFF anyMask: 16r0F.                                  "test if any bits set in mask set in receiver"
b := 16rFF noMask: 16r0F.                                   "test if all bits set in mask clear in receiver"```

So, you could write ((b1 & 0x3F) << 4) | (b2 >> 4) as

((b1 bitAnd: 16r3F) << 4) bitOr: (b2 >> 4)

Upvotes: 2

Related Questions