David
David

Reputation: 349

C# Left Shift Operator

There's a statement a co-worker of mine wrote which I don't completely understand. Unfortunately he's not available right now, so here it is (with modified names, we're working on a game in Unity).

private readonly int FRUIT_LAYERS =
          (1 << LayerMask.NameToLayer("Apple"))
        | (1 << LayerMask.NameToLayer("Banana"));

NameToLayer takes a string and returns an integer. I've always seen left shift operators used with the constant integer on the right side, not the left, and all the examples I'm finding via Google follow that approach. In this case, I think he's pushing Apple and Banana onto the same relative layer (which I'll use later for filtering). In the future there would be more "fruits" to filter by. Any brilliant stackoverflowers who can give me an explanation of what's happening on those lines?

Upvotes: 4

Views: 2662

Answers (4)

Martin Prikryl
Martin Prikryl

Reputation: 202504

1 << n is basically an equivalent to 2n.

Upvotes: 2

Servy
Servy

Reputation: 203844

1 << x is essentially saying "give me a number where the (x+1)-th bit is one and the rest of the numbers are all zero.

x | y is a bitwise OR, so it will go through each bit from 1 to n and if that bit is one in either x or y then that bit will be one in the result, if not it will be zero.

So if LayerMask.NameToLayer("Apple") returns 2 and LayerMask.NameToLayer("Banana") returns 3 then FRUIT_LAYERS will be a number with the 3rd and 4th bits set, which is 1100 in binary, or 12 in base 10.

Upvotes: 7

Timothy Shields
Timothy Shields

Reputation: 79541

Your coworker is essentially using an int in place of a bool[32] to try to save on space. The block of code you show is analogous to

bool[] FRUIT_LAYERS = new bool[32];
FRUIT_LAYERS[LayerMask.NameToLayer("Apple")] = true;
FRUIT_LAYERS[LayerMask.NameToLayer("Banana")] = true;

You might want to consider a pattern more like this:

[Flags]
enum FruitLayers : int
{
    Apple = 1 << 0,
    Banana = 1 << 1,
    Kiwi = 1 << 2,
    ...
}

private readonly FruitLayers FRUIT_LAYERS = FruitLayers.Apple | FruitLayers.Banana;

Upvotes: 3

Siraf
Siraf

Reputation: 1302

The code is shifting the binary value 1 to the left, the number of binary places to shift is determined by the Apple and Banana, after both values are shifted the are ORed in a binary way

Example: Assume apple returns 2 and banana returns 3 you get: 1 << 2 which is 0100 (that means 4 in decimal) 1 << 3 which is 1000 ( that means eight in decimal)

now 0100 bitwise or with 1000 is 1100 which means 12

Upvotes: 2

Related Questions