What does the operator "<<" mean in C#? - c#

I was doing some basic audio programming in C# using the NAudio package and I came across the following expression and I have no idea what it means, as i've never seen the << operator being used before. So what does << mean?
Please give a quick explaination of this expression.
short sample = (short)((buffer[index + 1] << 8) | buffer[index + 0]);

Definition
The left-shift operator (<<) shifts
its first operand left by the number
of bits specified by its second
operand. The type of the second
operand must be an int.
<< Operator (MSDN C# Reference)
For binary numbers it is a bitwise operation that shifts all of the bits of its operand; every bit in the operand is simply moved a given number of bit positions, and the vacant bit-positions are filled in.
Usage
Arithmetic shifts can be useful as efficient ways of performing multiplication or division of signed integers by powers of two. Shifting left by n bits on a signed or unsigned binary number has the effect of multiplying it by 2n. Shifting right by n bits on a two's complement signed binary number has the effect of dividing it by 2n, but it always rounds down (towards negative infinity). This is different from the way rounding is usually done in signed integer division (which rounds towards 0). This discrepancy has led to bugs in more than one compiler.
An other usage is work with color bits. Charles Petzold Foundations article "Bitmaps And Pixel Bits" shows an example of << when working with colors:
ushort pixel = (ushort)(green << 5 | blue);

Shift left (and the counterpart, Shift right) moves the bits in the given direction.
Shift left is more or less times 2, but faster
Shift right is more or less divided by 2, but faster

It's a left bit shift operation, a VERY common programming idiom: http://en.wikipedia.org/wiki/Arithmetic_shift

It's called left-shift operator.
Follow this link for more detailed information.

The bitwise operator has already been explained quite a few times already. Let's say that buffer[0] contains 1, buffer[1] contains 2 and index is 0 and replace these values:
short sample = (short)((buffer[1] << 8) | buffer[0]);
short sample = (short)((1 << 8) | 2);
Now, a semi-graphical representation. This is the numeral 1 in a binary representation:
0000 0001
Shifting eight positions to the left would make this number to "overflow" from a single byte. However, the compiler is smart enough to give us more room.
0000 0001 0000 0000
Now, the right part: the number 2 looks like this in binary:
0000 0010
And the "|" operator (bitwise OR) makes just put the two values together and comparing bit per bit.
0000 0001 0000 0000
| 0000 0000 0000 0010
= 0000 0001 0000 0010
And the final value is stored in your "sample" variable (in this case, 258.) The reverse operation is similar:
buffer[0] = sample & 255;
buffer[1] = (sample & (255 << 8)) >> 8;

Left shift
Here is some msdn to help you : http://msdn.microsoft.com/en-us/library/ayt2kcfb(VS.80).aspx

The "<<" is a shift left operator. x << y shifts bit pattern x y position left.
For example, if x was 0001 0101 and y was 1 then the result would be 0010 1010. It's like someone's pushed each bit left one.

As a few people have pointed out already it is a shift operation.
However It is worth noting that depending on whether the operand is a signed integral type or a unsigned integral type it will apply either an arithmetic or logical shift.
See the bottom of this page on msdn.

As others have said the << operator moves the bits of a number left. The normal reason why someone would do this in an Audio application is to combine two 8bit mono-samples (one for left and right) into a 16 bit sterio sample.
So in the sample code it looks like Buffer contains sterio encoded with left and right in alternate samples. By shifting the first left 8 and oring the second the author is combining them to form a 16bit sterio sample with the High 8bits being one channel and the low 8bits being the other.
If in your example the buffer contained:
1001 0100 (Right)
1001 0011 (Left)
The result you would get in sample is:
(Left) (Right)
1001 0011 1001 0100

Related

Why is the following bitshift operation not discarding the bit shifted to the left?

Let's say I wrote the following :
Console.WriteLine("{0:X8}", (uint)1 << 31);
It returns 80000000 (as expected).
However, If I wrote :
Console.WriteLine("{0:X8}", (uint)1 << 32);
It returns 00000001.
I would expect the "1" bit to be discarded and the result to be 00000000.
Here is what documentation says :
The left-shift operation discards the high-order bits that are outside
the range of the result type and sets the low-order empty bit
positions to zero.
Indeed, if I wrote this :
Console.WriteLine("{0:X8}", (uint)0xFA << 28);
It returns A0000000 (F is discarded)
From that same documentation page:
For the x << count and x >> count expressions, the actual shift count depends on the type of x as follows:
If the type of x is int or uint, the shift count is defined by the low-order five bits of the right-hand operand. That is, the shift count is computed from count & 0x1F (or count & 0b_1_1111).
32 & 0x1F is 0.
This "gotcha" is bad enough that former C# design team member Eric Lippert named it the 8th worst C# feature.

How does a logical & work on two bytes in C#?

I recently had a test question:
byte a,b,c;
a = 190;
b = 4;
c = (byte)(a & b);
What is the value of c?
I have never used a logical operand in this manner, what's going on here? Stepping through this, the answer is 4, but why?
Also, where would this come up in the real world? I would argue that using logical operands in this manner, with a cast, is just bad practice, but I could be wrong.
You are doing a bitwise AND in this case, not a logical AND, it is combining the bits of the two values of a & b and giving you a result that has only the bits set that are both set in a & b, in this case, just the 4s place bit.
190 = 10111110
& 4 = 00000100
-------------------
= 4 00000100
Edit: Interestingly, msdn itself makes the issue of whether to call it logical vs bitwise a bit muddy. On their description of the logical operators (& && | || etc) they say logical operators (bitwise and bool) but then on the description of & itself it indicates it performs a bitwise AND for integers and a logical AND for bools. It appears it is still considered a logical operator, but the action between integer types is a bitwise AND.
http://msdn.microsoft.com/en-us/library/sbf85k1c(v=vs.71).aspx
The logical AND operator, when applied to integers performs a bitwise AND operation. The result is 1 in each position in which a 1 appears in both of the operands.
0011
& 0101
------
0001
The decimal value 190 is equivalent to binary 10111110. Decimal 4 is binary 00000100.
Do a logical AND operation on the bits like this:
10111110
& 00000100
----------
00000100
So the result is 4.
Also, where would this come up in the real world? I would argue that using logical operands in this manner, with a cast, is just bad practice, but I could be wrong.
These operations are useful in several circumstances. The most common is when using Enum values as flags.
[Flags]
public enum MyFileOptions
{
None = 0,
Read = 1, // 2^0
Write = 2, // 2^1
Append = 4, // 2^2
}
If an Enum has values that are powers of two, then they can be combined into a single integer variable (with the Logical OR operator).
MyFileOptions openReadWrite = MyFileOptions.Read | MyFileOptions.Write;
In this variable, both bits are set, so it indicates that both the Read and Write options are selected.
The logical AND operator can be used to test values.
bool openForWriting = ((openReadWrite & MyFileOptions.Write) == MyFileOptions.Write);
NOTE
A lot of people are pointing out that this is actually a bitwise AND not a logical AND. I looked it up in the spec before I posted, and I was suprised to learn that both versions are referred to as "Logical AND" in the spec. This makes sense because it is performing the logical AND operation on each bit. So you are actually correct in the title of the question.
This is a bitwise AND, meaning the bits on both bytes are compared, and a 1 is returned if both bits are 1.
10111110 &
00000100
--------
00000100
One of the uses of a logical & on bytes is in networking and is called the Binary And Test. Basically, you logical and bytes by converting them to binary and doing a logical and on every bit.
In binary
4 == 100
190 == 10111110
& is and AND operation on the boolean operators, so it does de Binary and on 4 and 190 in byte format, so 10111110 AND 100 gives you 100, so the result is 4.
This is a bitwise AND, not a logical AND. Logical AND is a test of a condition ie:
if(a && b) doSomething();
A bitwise AND looks at the binary value of the two variables and combines them. Eg:
10101010 &
00001000
---------
00001000
This lines up the binary of the two numbers, like this:
10111110
00000100
--------
00000100
On each column, it checks to see if both numbers are 1. If it is, it will return 1 on the bottom. Otherwise, it will return 0 on the bottom.
I would argue that using logical operands in this manner, with a cast, is just bad practice, but I could be wrong.
There is no cast. & is defined on integers, and intended to be used this way. And just so everyone knows, this technically is a logical operator according to MSDN, which I find kind of crazy.

C# strange code

Anyone know what follow code does?
the question is about follow operators: & and |,and 0xfc
salt[0] = (byte)((salt[0] & 0xfc) | (saltLen & 0x03));
salt[1] = (byte)((salt[1] & 0xf3) | (saltLen & 0x0c));
salt[2] = (byte)((salt[2] & 0xcf) | (saltLen & 0x30));
salt[3] = (byte)((salt[3] & 0x3f) | (saltLen & 0xc0));
the question is about follow operators: & and |,and 0xfc
& is the bitwise and operator. See http://msdn.microsoft.com/en-us/library/sbf85k1c.aspx.
| is the bitwise or operator. See http://msdn.microsoft.com/en-us/library/kxszd0kx.aspx.
0xfc isn't an operator, it's an integer constant (i.e., a number). See http://msdn.microsoft.com/en-us/library/aa664674(VS.71).aspx and http://en.wikipedia.org/wiki/Hexadecimal.
Well the comment above explains what it's doing, but if you're looking for a breakdown of the operators:
Perform a bitwise and on
salt[i] and a hex number (the & operator).
Perform a bitwise and on salt[i]
and a second hex number.
Perform a bitwise or on the result of steps 1 and 2 (the | operator).
Cast the result of step 3 to a byte
Store the result in salt[i]
The result is what is noted in the comment block. The numbers of the format 0xc0 and whatnot are in hexadecimal, which is base 16. I.e. c0 in hex is equivalent to 16*12 + 16*0 = 192 in decimal. In hex, since you run out of digits at 9, you begin using letters. Thus, a=10, b=11, c=12, d=13, e=14, f=15, and f becomes the highest "digit" since you would move over by one place when you get to 16 (as 16 is the base).
See also:
Bitwise operation
Hexadecimal
// Split salt length (always one byte) into four two-bit pieces and
// store these pieces in the first four bytes of the salt array.
This is a cocky answer, but my intention is to indicate that it is already answered, so please let me know if you need more detail :)

Why arithmetic shift halfs a number only in SOME incidents?

Hey, I'm self-learning about bitwise, and I saw somewhere in the internet that arithmetic shift (>>) by one halfs a number. I wanted to test it:
44 >> 1 returns 22, ok
22 >> 1 returns 11, ok
11 >> 1 returns 5, and not 5.5, why?
Another Example:
255 >> 1 returns 127
127 >> 1 returns 63 and not 63.5, why?
Thanks.
The bit shift operator doesn't actually divide by 2. Instead, it moves the bits of the number to the right by the number of positions given on the right hand side. For example:
00101100 = 44
00010110 = 44 >> 1 = 22
Notice how the bits in the second line are the same as the line above, merely
shifted one place to the right. Now look at the second example:
00001011 = 11
00000101 = 11 >> 1 = 5
This is exactly the same operation as before. However, the result of 5 is due to the fact that the last bit is shifted to the right and disappears, creating the result 5. Because of this behavior, the right-shift operator will generally be equivalent to dividing by two and then throwing away any remainder or decimal portion.
11 in binary is 1011
11 >> 1
means you shift your binary representation to the right by one step.
1011 >> 1 = 101
Then you have 101 in binary which is 1*1 + 0*2 + 1*4 = 5.
If you had done 11 >> 2 you would have as a result 10 in binary i.e. 2 (1*2 + 0*1).
Shifting by 1 to the right transforms sum(A_i*2^i) [i=0..n] in sum(A_(i+1)*2^i) [i=0..n-1]
that's why if your number is even (i.e. A_0 = 0) it is divided by two. (sorry for the customised LateX syntax... :))
Binary has no concept of decimal numbers. It's returning the truncated (int) value.
11 = 1011 in binary. Shift to the right and you have 101, which is 5 in decimal.
Bit shifting is the same as division or multiplication by 2^n. In integer arithmetics the result gets rounded towards zero to an integer. In floating-point arithmetics bit shifting is not permitted.
Internally bit shifting, well, shifts bits, and the rounding simply means bits that fall off an edge simply getting removed (not that it would actually calculate the precise value and then round it). The new bits that appear on the opposite edge are always zeroes for the right hand side and for positive values. For negative values, one bits are appended on the left hand side, so that the value stays negative (see how two's complement works) and the arithmetic definition that I used still holds true.
In most statically-typed languages, the return type of the operation is e.g. "int". This precludes a fractional result, much like integer division.
(There are better answers about what's 'under the hood', but you don't need to understand those to grok the basics of the type system.)

C/C++ Date Solution/Conversion

I need to come up with a way to unpack a date into a readable format. unfortunately I don't completely understand the original process/code that was used.
Per information that was forwarded to me the date was packed using custom C/Python code as follows;
date = year << 20;
date |= month << 16;
date |= day << 11;
date |= hour << 6;
date |= minute;
For example, a recent packed date is 2107224749 which equates to Tuesday Sept. 22 2009 10:45am
I understand....or at least I am pretty sure....the << is shifting the bits but I am not sure what the "|" accomplishes.
Also, in order to unpack the code the notes read as follows;
year = (date & 0xfff00000) >> 20;
month = (date & 0x000f0000) >> 16;
day = (date & 0x0000f800) >> 11;
hour = (date & 0x000007c0) >> 6;
minute = (date & 0x0000003f);
Ultimately, what I need to do is perform the unpack and convert to readable format using either JavaScript or ASP but I need to better understand the process above in order to develop a solution.
Any help, hints, tips, pointers, ideas, etc. would be greatly appreciated.
The pipe (|) is bitwise or, it is used to combine the bits into a single value.
The extraction looks straight-forward, except I would recommend shifting first, and masking then. This keeps the constant used for the mask as small as possible, which is easier to manage (and can possibly be a tad more efficient, although for this case that hardly matters).
Looking at the masks used written in binary reveals how many bits are used for each field:
0xfff00000 has 12 bits set, so 12 bits are used for the year
0x000f0000 has 4 bits set, for the month
0x0000f800 has 5 bits set, for the day
0x000007c0 has 5 bits set, for the hour
0x0000003f has 6 bits set, for the minute
The idea is exactly what you said. Performing "<<" just shifts the bits to the left.
What the | (bitwise or) is accomplishing is basically adding more bits to the number, but without overwriting what was already there.
A demonstration of this principle might help.
Let's say we have a byte (8 bits), and we have two numbers that are each 4 bits, which we want to "put together" to make a byte. Assume the numbers are, in binary, 1010, and 1011. So we want to end up with the byte: 10101011.
Now, how do we do this? Assume we have a byte b, which is initialized to 0.
If we take the first number we want to add, 1010, and shift it by 4 bits, we get the number 10100000 (the shift adds bytes to the right of the number).
If we do: b = (1010 << 4), b will have the value 10100000.
But now, we want to add the 4 more bits (0011), without touching the previous bits. To do this, we can use |. This is because the | operator "ignores" anything in our number which is zero. So when we do:
10100000 (b's current value)
|
00001011 (the number we want to add)
We get:
10101011 (the first four numbers are copied from the first number,
the other four numbers copied from the second number).
Note: This answer came out a little long, I'm wikiing this, so, if anyone here has a better idea how to explain it, I'd appreciate your help.
These links might help:
http://www.gamedev.net/reference/articles/article1563.asp
http://compsci.ca/v3/viewtopic.php?t=9893
In the decode section & is bit wise and the 0xfff00000 is a hexadecimal bit mask. Basically each character in the bit mask represents 4 bits of the number. 0 being 0000 in binary and f being 1111 so if you look at the operation in binary you are anding 1111 1111 1111 0000 0000 ... with whatever is in date so basically you are getting the upper three nibbles(half bytes) and shifting them down so that 00A00000 gives you 10(A in hex) for the year.
Also note that |= is like += it is bit wise or then assignment rolled in to one.
Just to add some practical tips:
minute = value & ((1 << 6)-1);
hour = (value >> 6) & ((1<<5)-1); // 5 == 11-6 == bits reserved for hour
...
1 << 5 creates a bit at position 5 (i.e. 32=00100000b),
(1<<5)-1 cretaes a bit mask where the 5 lowest bits are set (i.e. 31 == 00011111b)
x & ((1<<5)-1) does a bitwise 'and' preserving only the bits set in the lowest five bits, extracting the original hour value.
Yes the << shifts bits and the | is the bitwise OR operator.

Categories