136

Why is && preferable to & and || preferable to |?

I asked someone who's been programming for years and his explanation was:

For example, in if (bool1 && bool2 && bool3) { /*DoSomething*/ }, bool1 has to be true for it to test bool2 which has to be true before moving on to bool3, etc. If I'd used a single & instead there is no order to the test even if all of them have to be true to progress to the next line, so why does it matter anyway?

Note: I'd like to point out that I'm the programming equivalent of a toddler and this is not a serious or urgent question. It's more a matter of understanding why things should be done a certain way as opposed to another.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Dani
  • 2,480
  • 3
  • 21
  • 27
  • 56
    & and && | and || are completely different operators – Felice Pollano Sep 07 '11 at 09:42
  • That's only true in a conditional statement. – Rune FS Sep 07 '11 at 09:47
  • 3
    Retagged, as this doesn't only apply to C# – Jonathan Dickinson Sep 07 '11 at 09:56
  • 12
    Reverted, because the answers are already specific to C# and the inner workings might differ a bit in other languages that have generally the same concept. – Daniel Hilgarth Sep 07 '11 at 09:57
  • 8
    @Felice: They are different, but hardly *completely different.* They are in fact very similar: `x & y` and `x && y` will always evaluate to the same result if x and y are expressions of boolean type. In fact the only difference in that case seems to be that in `x & y`, y is always evaluated. – Joren Sep 07 '11 at 10:57
  • @Joren: AndAlso (yes, a joke!) one more thing: & can also be a binary AND, whereas && cannot; conversely with | vs ||. – The Dag Sep 07 '11 at 13:39
  • @The Dag: Indeed, that's why I bothered to say 'expressions of boolean type'. – Joren Sep 07 '11 at 15:24
  • personally I find the double operators like && || quite pointless and useless versus textual ones like "and" and "or". They are usable by default with G++, not with visual C++. – jokoon Sep 08 '11 at 11:32
  • See http://blog.dmbcllc.com/2009/03/16/vs-and-vs-whats-the-difference/ – Robert Harvey Sep 10 '11 at 06:09
  • Is there any performance gain when using any of those two possibilities? – slawekwin Sep 13 '11 at 06:05
  • 1
    @slawekin: I'd suggest to read through the answers. Some extensively write about the performance differences. The answer might surprise you though. – Abel Sep 13 '11 at 17:40

16 Answers16

183

In most cases, && and || are preferred over & and | because the former are short-circuited, meaning that the evaluation is canceled as soon as the result is clear.

Example:

if(CanExecute() && CanSave())
{
}

If CanExecute returns false, the complete expression will be false, regardless of the return value of CanSave. Because of this, CanSave is not executed.

This is very handy in the following circumstance:

string value;
if(dict.TryGetValue(key, out value) && value.Contains("test"))
{
    // Do Something
}

TryGetValue returns false if the supplied key is not found in the dictionary. Because of the short-circuiting nature of &&, value.Contains("test") is only executed, when TryGetValue returns true and thus value is not null. If you would use the bitwise AND operator & instead, you would get a NullReferenceException if the key is not found in the dictionary, because the second part of the expression is executed in any case.

A similar but simpler example of this is the following code (as mentioned by TJHeuvel):

if(op != null && op.CanExecute())
{
    // Do Something
}

CanExecute is only executed if op is not null. If op is null, the first part of the expression (op != null) evaluates to false and the evaluation of the rest (op.CanExecute()) is skipped.

Apart from this, technically, they are different, too:
&& and || can only be used on bool whereas & and | can be used on any integral type (bool, int, long, sbyte, ...), because they are bitwise operators. & is the bitwise AND operator and | is the bitwise OR operator.

To be very exact, in C#, those operators (&, | [and ^]) are called "Logical operators" (see the C# spec, chapter 7.11). There are several implementations of these operators:

  1. For integers (int, uint, long and ulong, chapter 7.11.1):
    They are implemented to compute the bitwise result of the operands and the operator, i.e. & is implement to compute the bitwise logical AND etc.
  2. For enumerations (chapter 7.11.2):
    They are implemented to perform the logical operation of the underlying type of the enumeration.
  3. For bools and nullable bools (chapter 7.11.3 and 7.11.4):
    The result is not computed using bitwise calculations. The result is basically looked up based on the values of the two operands, because the number of possibilities is so small.
    Because both values are used for the lookup, this implementation isn't short-circuiting.
Daniel Hilgarth
  • 171,043
  • 40
  • 335
  • 443
  • 32
    This can also be handy for checking if something is null. For example: `if(op != null && op.CanExecute())`. Because the second cause isnt evaluated when the first isnt true, this is valid. – TJHeuvel Sep 07 '11 at 09:44
  • 2
    @TJHeuvel: This is basically the same usage I described with my `TryGetValue` example. But yes, it's another good example of this. – Daniel Hilgarth Sep 07 '11 at 09:45
  • 4
    Good answer. Maybe you should also add an example of how `&` or `|` is used with non-bool arguments (i.e. what the operators do) for the benefit of all persons new. – Zabba Sep 07 '11 at 09:52
82

To explain very clearly what this means (even though the other answers hint at it - but probably use terminology you don't understand).

The following code:

if (a && b)
{
   Foo();
}

Is really compiled to this:

if (a)
{
    if (b)
    {
        Foo();
    }
}

Where the following code is compiled exactly as it is represented:

if (a & b)
{
   Foo();
}

This is called short-circuiting. In general you should always use && and || in your conditions.

Bonus Marks: There is one scenario when you shouldn't. If you are in a situation where performance is crucial (and this is nano-seconds crucial) only use short-circuiting when you must (e.g. null checking) - as a short-circuit is a branch/jump; which could result in a branch-misprediction on your CPU; an & is much cheaper than &&. There is also a scenario where short-circuiting can actually break logic - have a look at this answer of mine.

Diatribe/Monologue: Regarding the branch mis-prediction that most blissfully ignore. Quoting Andy Firth (who has been working on games for 13 years): "This may be lower level that people think they need to go... but they'd be wrong. Understanding how the hardware you're programming for treats branches can affect performance to a HUGE degree... far more than most programmers may appreciate re: death by a thousand cuts."

  • Game developers (and others working in extreme real-time conditions) go as far as restructuring their logic to better suit the predictor. There is also evidence of this in decompiled mscorlib code.
  • Just because .NET shields you from this type of thing doesn't mean it's not important. A branch mis-prediction is horribly expensive at 60 Hz; or at 10,000 requests/second.
  • Intel wouldn't have tools to identify the location of mis-predictions, nor would Windows have a performance counter for this, nor would there be a word to describe it, were it not a problem.
  • Ignorance about the lower levels and architecture does not make someone who is aware of them wrong.
  • Always try to understand the limitations of the hardware you are working on.

Here is a benchmark for the non-believers. It's best to run the process in RealTime/High to mitigate the scheduler having an effect: https://gist.github.com/1200737

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jonathan Dickinson
  • 9,050
  • 1
  • 37
  • 60
  • 8
    About the "bonus marks": We all know the good that comes out of premature optimization. :) – user Sep 07 '11 at 12:22
  • 7
    @Michael - that's why 'nano-seconds crucial' is in bold :). AAA game developers typically worry about stuff like this - and you never know who will read the answers; so it's always best to document even the borderline/extreme cases. – Jonathan Dickinson Sep 07 '11 at 12:30
  • Yes, but in probably 99.9% of the cases, readability and predictability (you see what you want to see) should trump performance at that level. Also, your answer applies only to using the operators in boolean expressions. As Daniel Hilgarth pointed out, `&` and `|` are valid in contexts where `&&` and `||` are not. – user Sep 07 '11 at 12:33
  • 1
    Is that bonus mark valid for C#? I'd have thought not, as MSIL is interpreted, unless the expression is compiled right down to machine code. – Jeremy McGee Sep 07 '11 at 12:36
  • Even with nanoseconds being crucial, short-circuiting can still perform better - if the first operand always triggers the short-circuiting, then branch prediction will make it faster than when you have the additional cost of evaluating the second operand. – tdammers Sep 07 '11 at 12:37
  • 7
    @Jeremy MSIL is not interpreted. – Jonathan Dickinson Sep 07 '11 at 12:40
  • 1
    @tdammers - yes but in the case where you are not calling a method (but have, say, a local simple variable) it will be that *tiny* amount faster. It's there for completeness, and also in the spirit that I did try to get the question edited to most 'C-variants', not just C# (because it does really apply to most variants, even C itself). – Jonathan Dickinson Sep 07 '11 at 12:42
  • If you guys want to discuss it more I am in the [C#](http://chat.stackoverflow.com/rooms/7/c) room. – Jonathan Dickinson Sep 07 '11 at 12:46
  • @jonathan dickinson: Brain f*rt here. You're right. (Reference: http://msdn.microsoft.com/en-us/library/zw4w595w.aspx) – Jeremy McGee Sep 07 '11 at 12:46
  • @Jonathan Dickinson: I have difficulty buying your explanation and especially the claim that short-circuiting is inefficient. For one thing, I've always heard the opposite, that short-circuiting is an optimization. More importantly, a little reflection should give you pause when you claim that "if (x && y)" can somehow directly correspond to machine code. I would like to know, on x86 for instance, what opcode that is supposed to be. – The Dag Sep 07 '11 at 13:50
  • @The Dag, I agree that short-circuited evaluation is unlikely to be slower. The branch distances are very short, so the cost to the CPU from making a bad branch prediction is minimal. The overhead of doing field dereferencing (possibly causing a data memory cache miss) or, worse yet, calling a method, may be much worse than a local branch instruction. Even then, the differences are so miniscule as to be negligible. – Dan Bryant Sep 07 '11 at 14:10
  • 2
    @TheD recheck answer - I have added a monologue about why you SHOULD be worred about this. And, FYI, `(x && y)` translates to `LOAD x; BRANCH_FALSE; LOAD y; BRANCH_FALSE;` where `(x & y)` translates to `LOAD x; LOAD y; AND; BRANCH_FALSE;`. One branch versus two. – Jonathan Dickinson Sep 07 '11 at 14:10
68

Logical operator (|| and &&) vs. bitwise operator (| and &).

The most crucial difference between a logical operator and bitwise operator is that a logical operator takes two booleans and produces a boolean while a bitwise operator takes two integers and produces an integer (note: integers means any integral data type, not just int).

To be pedantic, a bitwise operator takes a bit-pattern (e.g. 01101011) and does a bit-wise AND/OR on each bits. So, for example if you have two 8-bit integers:

a     = 00110010 (in decimal:    32+16+2   = 50)
b     = 01010011 (in decimal: 64+   16+2+1 = 83)
----------------
a & b = 00010010 (in decimal:       16+2   = 18)
a | b = 01110011 (in decimal: 64+32+16+2+1 = 115)

while a logical operator only works in bool:

a      = true
b      = false
--------------
a && b = false
a || b = true

Second, it is often possible to use a bitwise operator on bool since true and false is equivalent to 1 and 0 respectively, and it happens that if you translate true to 1 and false to 0, then do bitwise operation, then convert non-zero to true and zero to false; it happens that the result will be the same had you just used logical operator (check this for exercise).

Another important distinction is also that a logical operator is short-circuited. Thus, in some circles[1], you often see people doing something like this:

if (person && person.punch()) {
    person.doVictoryDance()
}

which translates to: "if person exists (i.e. is not null), try to punch him/her, and if the punch succeeds (i.e. returns true), then do a victory dance".

Had you used a bitwise operator instead, this:

if (person & person.punch()) {
    person.doVictoryDance()
}

will translate to: "if person exists (i.e. is not null) and the punch succeeds (i.e. returns true), then do a victory dance".

Note that in the short-circuited logical operator, the person.punch() code may not be run at all if person is null. In fact, in this particular case, the second code would produce a null reference error if person is null, since it tries to call person.punch() no matter whether person is null or not. This behavior of not evaluating the right operand is called short-circuiting.

[1] Some programmers will baulk for putting a function call that have a side effect inside an if expression, while for others it's a common and very useful idiom.

Since a bitwise operator works on 32-bits at a time (if you're on a 32-bit machine), it can lead to a more elegant and faster code if you need to compare a huge number of conditions, e.g.

int CAN_PUNCH = 1 << 0, CAN_KICK = 1 << 1, CAN_DRINK = 1 << 2, CAN_SIT = 1 << 3,
    CAN_SHOOT_GUNS = 1 << 4, CAN_TALK = 1 << 5, CAN_SHOOT_CANNONS = 1 << 6;

Person person;
person.abilities = CAN_PUNCH | CAN_KICK | CAN_DRINK | CAN_SIT | CAN_SHOOT_GUNS;

Place bar;
bar.rules = CAN_DRINK | CAN_SIT | CAN_TALK;

Place military;
military.rules = CAN_SHOOT_CANNONS | CAN_PUNCH | CAN_KICK | CAN_SHOOT_GUNS | CAN_SIT;

CurrentLocation cloc1, cloc2;
cloc1.usable_abilities = person_abilities & bar_rules;
cloc2.usable_abilities = person_abilities & military_rules;

// cloc1.usable_abilities will contain the bit pattern that matches `CAN_DRINK | CAN_SIT`
// while cloc2.usable_abilities will contain the bit pattern that matches `CAN_PUNCH | CAN_KICK | CAN_SHOOT_GUNS | CAN_SIT`

Doing the same with logical operators would require an awkward amount of comparisons:

Person person;
person.can_punch = person.can_kick = person.can_drink = person.can_sit = person.can_shoot_guns = true;
person.can_shoot_cannons = false;

Place bar;
bar.rules.can_drink = bar.rules.can_sit = bar.rules.can_talk = true;
bar.rules.can_punch = bar.rules.can_kick = bar.rules.can_shoot_guns = bar.rules.can_shoot_cannons = false;

Place military;
military.rules.can_punch = military.rules.can_kick = military.rules.can_shoot_guns = military.rules.can_shoot_cannons = military.rules.can_sit = true;
military.rules.can_drink = military.rules.can_talk = false;

CurrentLocation cloc1;
bool cloc1.usable_abilities.can_punch         = bar.rules.can_punch         && person.can_punch,
     cloc1.usable_abilities.can_kick          = bar.rules.can_kick          && person.can_kick,
     cloc1.usable_abilities.can_drink         = bar.rules.can_drink         && person.can_drink,
     cloc1.usable_abilities.can_sit           = bar.rules.can_sit           && person.can_sit,
     cloc1.usable_abilities.can_shoot_guns    = bar.rules.can_shoot_guns    && person.can_shoot_guns,
     cloc1.usable_abilities.can_shoot_cannons = bar.rules.can_shoot_cannons && person.can_shoot_cannons
     cloc1.usable_abilities.can_talk          = bar.rules.can_talk          && person.can_talk;

bool cloc2.usable_abilities.can_punch         = military.rules.can_punch         && person.can_punch,
     cloc2.usable_abilities.can_kick          = military.rules.can_kick          && person.can_kick,
     cloc2.usable_abilities.can_drink         = military.rules.can_drink         && person.can_drink,
     cloc2.usable_abilities.can_sit           = military.rules.can_sit           && person.can_sit,
     cloc2.usable_abilities.can_shoot_guns    = military.rules.can_shoot_guns    && person.can_shoot_guns,
     cloc2.usable_abilities.can_talk          = military.rules.can_talk          && person.can_talk,
     cloc2.usable_abilities.can_shoot_cannons = military.rules.can_shoot_cannons && person.can_shoot_cannons;

A classical example where bit-patterns and bitwise operator are used is in Unix/Linux file system permissions.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Lie Ryan
  • 62,238
  • 13
  • 100
  • 144
  • 3
    the example seems a bit violent, but seems like other answers focused too much on short circuiting and not enough on the difference between operating on integers and on booleans. – Roman Sep 12 '11 at 13:43
  • Function must be understood before implementation details (short-circtuit/side effects) come into play. Glad you cleared up the main difference being boolean vs integer logic, not short-circuiting. – Abel Sep 13 '11 at 17:38
8

In the case of:

if (obj != null && obj.Property == true) { }

would work as expected.

But:

if (obj != null & obj.Property == true) { }

could potentially throw a null reference exception.

fatty
  • 2,453
  • 2
  • 25
  • 24
2

Short and simple:

1 && 2 = true
because
1 = true (non-zero) in C
2 = true (non-zero) in C

true ANDS logically with true to give true.

But

1 & 2 = 0 = false
because
1 = 0001 in binary
2 = 0010 in binary

0001 ANDs bitwise with 0010 to give 0000 = 0 in decimal.

Likewise for || and | operators too...!

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Shrey
  • 2,374
  • 3
  • 21
  • 24
1

If you are an old-timer C programmer, be careful. C# has really surprised me.

MSDN says for the | operator:

Binary | operators are predefined for the integral types and bool. For integral types, | computes the bitwise OR of its operands. For bool operands, | computes the logical OR of its operands; that is, the result is false if and only if both its operands are false.

(Emphasis is mine.) Boolean types are handled specially, and in this context the question only starts to make sense, and the difference is, as other already expained in their answers:

&& and || are short-circuiting. & and | evaluate both operands.

and what's preferable depends on many things like side-effects, performance and code readability, but generally the short-circuiting operators are preferable also because they are better understood by people with a similar background like me.

The reason is: I would argument like this: Since there is no real boolean type in C, you could use the bitwise operator | and have its result evaluated as truthy or falsy in an if condition. But this is the wrong attitude for C#, because there is already a special case for boolean types.

nalply
  • 26,770
  • 15
  • 78
  • 101
1

C# Operators should explain why:

Essentially having two &'s or |'s means that it is a conditional rather than a logical, so you can tell the difference between the two.

& Operator has an example of using one &.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Stuart Thomson
  • 509
  • 5
  • 21
1

&& is the short circuit version of &.

If we are evaluating false & true, we already know from looking at the first argument that the result will be false. The && version of the operator will return a result as soon as it can, rather than evaluate the whole expression. There is also a similar verion of the | operator, ||.

mdm
  • 12,480
  • 5
  • 34
  • 53
1
if (list.Count() > 14 && list[14] == "foo")

is safe

if (list.Count() > 14 & list[14] == "foo")

would crash if the list doesn't have the right size.

jalf
  • 243,077
  • 51
  • 345
  • 550
  • I can't imagine someone can write "if (list.Count() > 14 & list[14] == "foo")" instead of "if (list.Count() > 14 && list[14] == "foo")". & just simply and naturally cannot be used for && in this case even if &'s is surely safe (list[1] for example). – Tien Do Sep 09 '11 at 04:25
1

OK, on face value

    Boolean a = true;
    Boolean b = false;

    Console.WriteLine("a({0}) && b({1}) =  {2}", a, b, a && b);
    Console.WriteLine("a({0}) || b({1}) =  {2}", a, b, a || b);
    Console.WriteLine("a({0}) == b({1}) =  {2}", a, b, a == b);

    Console.WriteLine("a({0}) & b({1}) =  {2}", a, b, a & b);
    Console.WriteLine("a({0}) | b({1}) =  {2}", a, b, a | b);
    Console.WriteLine("a({0}) = b({1}) =  {2}", a, b, a = b);

produce the same answer. However, as you showed, if you have a more complex question so:

if (a and b and c and d) ..

If a is not true and maybe b is a function where it has to go off, connect to something, get this, do that, make a decision.. why bother? Waste of time, you know it's already failed. Why make the machine go off and do extra pointless work?

I've always used && because I put the most likely to fail first, ergo, less calculations before moving on when there is no point. If there is no way to predict less likely choices, such as you have a boolean to limit output of data, something like:

if (limit && !MyDictionary.ContainsKey("name")) 
    continue;

If it's not limit, don't bother checking for the key, which could take longer..

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
BugFinder
  • 17,474
  • 4
  • 36
  • 51
1

When used in a logical expression such as an if statement && preferable because it will stop evaluating expressions as soon as the first false result is encountered. This is possible because a false value will cause the entire expression to be false. Similarly (and again in logical expressions) || is preferable because it will stop evaluating expressions as soon as it encounters a true expression because any true value will cause the entire expression to be true.

If however the expressions being or-ed or and-ed together have side effects, and you want all of these to happen as a result of your expression (regardless of the outcome of the logical expression), then & and | could be used. Conversely, the && and || operators can be useful as guards against unwanted side-effects (such as a null pointer causing an exception to be thrown).

The & and | operators can also be used with integers and in this case they produce an integer result which is the two operands and-ed or or-ed together at the bit level. This can be useful when an integer value's binary bits are used as an array of true and false values. To test whether a certain bit is on or off, a bit-mask is bitwise and-ed with the value. To turn a bit on, the same mask can be bitwise or-ed with the value. Finally to turn a bit off, the bitwise complement (using ~) of a mask is bitwise and-ed with the value.

int a = 0; // 0 means all bits off
a = a | 4; // set a to binary 100
if ((a & 4) != 0) {
    // will do something
}
a = a & (~4) // turn bit off again, a is now 000

In languages other than C#, care must be taken with the logical versus bitwise modes of & and |. In the code above, the if statement's conditional expression (a & 4) != 0 is a safe way to express this condition, but in many C like languages, conditional statements can simply treat zero integer values as false and non-zero integer values as true. (The reason for this relates to the conditional branch processor instructions available, and their relationship to the zero flag that is updated after every integer operation.) So the ìf statement's test for zero can be removed and the condition could be shortened to (a & 4).

This could cause confusion and maybe even problems when expressions combined using the bitwise and operator return values that don't have bits that line up. Consider the following example where the side-effects of two functions are desired, before checking that they were both successful (as defined by them returning a non-zero value):

if (foo() & bar()) {
    // do something
}

In C, if foo() returns 1 and bar() returns 2, the "something" won't be done because 1 & 2 is zero.

C# requires conditional statements like if to have a boolean oeprand, and the language doesn't allow an integer value to be cast to a boolean value. So the code above would generate compiler errors. It would more correctly be expressed as follows:

if (foo() != 0 & bar() != 0) {
    // do something
}
graza
  • 383
  • 2
  • 8
0

Simply,

if exp1 && exp2

if exp1 is flase don't check exp2

but

if exp1 & exp2

if exp1 is false Or true check exp2

and rarely people use & because they rarely want to check exp2 if exp1 is false

Fady
  • 201
  • 3
  • 8
  • 16
0

It's important, because if the cost of evaluation of bool2 (for instance) is high but bool1 is false, then you've saved yourself a fair bit of computation by using && over &

spender
  • 117,338
  • 33
  • 229
  • 351
0

Because && and || are used for flow control just like if/else are. It isn’t always about conditionals. It is perfectly reasonable to write as a statement, not as an if or a while conditional, the following:

 a() && b() && c() && d();

or even

 w() || x() || y() || z();

It’s not just that it those are easier to type than the equivalent if/else versions; they are also much easier to read and understand.

tchrist
  • 78,834
  • 30
  • 123
  • 180
0

&& and & mean two very different things and give you two different answers.

1 && 2 yields 1 ("true")
1 & 2 yields 0 ("false")

&& is a logic operator -- it means "true if both of the operands are true"
& is a bitwise comparison. It means "tell me which of the bits are set in both of the operands"

tylerl
  • 30,197
  • 13
  • 80
  • 113
  • 2
    The question is about C#. In C#, there is no way to cast a number to a bool, so 0 is not 'false' and nonzero is not 'true'; there is simply no equivalence. – Nate C-K Sep 13 '11 at 17:17
  • To convert number to bool, in a way that 1 means true and 0 means false, say "n!=0" (I assume... I'm not really familiar with C#). Actually I wanted to retract this comment since it's not well-researched and I don't think it's helpful or really relevant to the previous comment now that I think more about it, but I accidentally hit enter and now I don't think I can cancel it so here ya go, for whatever it's worth :-) – Don Hatch Jul 11 '13 at 16:12
  • `1 && 2` gives a compiler error: *"Error 4 Operator '&&' cannot be applied to operands of type 'int' and 'int'"* – Peter Mortensen May 01 '18 at 23:04
0

Quickest (and slightly dumbed down) way to explain this to people who do not NEED to know the exact operations of the code when doing this is

&& is doing a check on each of those conditions Until it finds a false and returns the entire outcome as false

|| is doing a check on each of those conditions Until it finds a true and returns the entire outcome as true.

& is doing MATHS based apon BOTH/ALL the conditions and dealing with the outcome.

| is doing MATHS based apon BOTH/ALL the conditions and dealing with the outcome.

I've never come across a point where I have needed to use & or | within an if statement. I mostly use it for cutting up Hexadecimal values into its component colours using bitwise shift.

EG:

r = fullvalue >> 0xFF & 0xFF;
g = fullvalue >> 0xF & 0xFF;
b = fullvalue & 0xFF;

Within this operation "& 0xFF" is forcing to only look at of the binary value. I have not personally found a use for | yet though.

WORMSS
  • 1,625
  • 28
  • 36