C#.net bitwise shift left operation.? [duplicate] - c#

This question already has answers here:
What are bitwise shift (bit-shift) operators and how do they work?
(10 answers)
Closed 8 years ago.
var x = 2;
var y=x+2<<2;
Console.WriteLine(y);
output = 16
my doubt is that how 16 is come.i know about bitwise shift left operator.what kind of operation is done.

Pay attention to operator precedence. 2 + 2 << 2 is not 2 + (2 << 2).

its same as below :-
x + 2 = 4;
4 << 2 ////it means 16 if you perform bitwise on this.
Desciption to understand Let shift operation :-
Shifts bits to the left. The number to the left of the operator is
shifted the number of places specified by the number to the right.
Each shift to the left doubles the number, therefore each left shift
multiplies the original number by 2. Use the left shift for fast
multiplication or to pack a group of numbers together into one larger
number. Left shifting only works with integers or numbers which
automatically convert to an integer such at byte and char.
so in your case lets say presentation for 4 is 100 and it would be shifted by 2 so it becomes 10000 which is presentation of 16 :-
for 4 :- 100
left shift by 2 so,
10000 ////Which is 16

Related

How do I inverse this bitwise operation?

I have the below code and I can't understand why the last line doesn't return 77594624. Can anyone help me write the inverse bitwise operation to go from 77594624 to 4 and back to 77594624?
Console.WriteLine(77594624);
Console.WriteLine((77594624 >> 24) & 0x1F);
Console.WriteLine((4 & 0x1F) << 24);
When you bit shift a value you might "lose" bits during that operation. If you right shift the value 16, which is 0b10000 in binary, by 4, you will get 1.
0b10000 = 16
0b00001 = 1
But this is also the case for other numbers like 28, which is 0b11100.
0b11100 = 28 = 16 + 8 + 4
0b00001 = 1
So with the start point 1 you cannot go "back" to the original number by left shifting again, as there is not enough information/bits available, you don't know if you want to go back to 16 or 28.
77594624 looks like this in binary, and the x's mark the part that is extracted by the right shift and bitwise AND:
000001000101000000000000000000000
xxxxx
Clearly some information is lost.
If the other parts of the number were available as well, then they could be reassembled.

Calculate the total amount (number) of combinations of a set with the specified combination length? [duplicate]

This question already has answers here:
Calculating all possible sub-sequences of a given length (C#)
(4 answers)
Closed 5 years ago.
Having a set of elements, which in this case is an Array of 3 characters/elements {A, B, C}:
char[] charSet = "ABC".ToCharArray();
I would like to write a generic usage function to help determine which would be the total amount of combinations that can be generated OF THE SPECIFIED LENGTH and determining too the amount of possible combinations with and without repetition. To avoid possible mistakes: this question is not about combo/perm generation, just calculation.
A simple uncompleted example to understand me:
public static long CalculateCombinations(int setLength, int comboLength, bool allowRepetition)
{
return result;
}
( where setLength is the amount of elements in the set, comboLength is the desired length of each combination, and allowRepetition a deterministic flag to help calculate the amount of combinations when and when not elements repetition is allowed in each combination. )
Then, if I have the same character set specified above, and I want to calculate the amount of possible combinations with repetition, the algorithm should return a value of 9, which would be the equivalent amount to this serie of combinations:
1: AA
2: AB
3: AC
4: BA
5: BB
6: BC
7: CA
8: CB
9: CC
The same algorithm should return me a value of 6 if I dont want repetition, which would be the equivalent amount to this serie of combinations:
1: AB
2: AC
3: BA
4: BC
5: CA
6: CB
Basically I'm trying to reproduce what this online service can do: http://textmechanic.com/text-tools/combination-permutation-tools/combination-generator/ however I tried to investigate and implement different 'nCr' formulas around the WWW (like http://www.vcskicks.com/code-snippet/combination.php ) and StackOverflow threads (like https://stackoverflow.com/a/26312275/1248295 ), but i don't get it how to calculate it when the combination length factor and repetition is involved in the calculation. Maybe this could be too basic than what it appears to me, but maths are not my forte.
My question: how can I write an algorithm that can calculate what I explained?. Would be very grateful if someone could link a formula and its implementation in C# or VB.NET.
Let's try it with three characters, A, B and C (n = 3) and combo length of k = 2, as your example states.
With repetition
We start with two empty spaces.
The first empty space can be filled in 3 possible ways.
For each of three possible ways, the second space can be filled in another three possible ways.
This gives you a total of 3 × 3 possibilities.
In general, there are n ^ k possibilities.
Without repetition
We start with two empty spaces.
The first empty space can be filled in 3 possible ways.
The second empty space can be filled in 2 possible ways, because you don't want to repeat yourself.
This gives you 3 × 2 possibilities in your case.
Let's go with another example. Say, you have five letters (ABCDE) and combo length of four _ _ _ _.
We put any of five letters on the first empty space. This is five possibilities: A, B, C, D, E.
Now for each possibility after the last step, no matter which letter we've chosen, now we have 4 letters left to choose from. If in the previous step we've chosen A, the corpus is now BCDE -- this is four possibilities. For B, we choose from ACDE -- this is again for possibilities. In total, since there were 5 ways to do previous step, and there are 4 ways to go after any of the previous choices, in total this is 20 possibilities: (AB, AC, AD, AE), (BA, BC, BD, BE), (CA, CB, CD, CE), (DA, DB, DC, DE), (EA, EB, EC, ED).
Let's keep going. After picking two letters, we're left with 3. With the same logic as before, for each of the previous 20 possibilities we have another 3 possibilities. This is 60 in total.
And one more space left. We have two letters which we haven't chosen before. From any of the previous 60 possibilities, we now have two possibilities. That's 120 in total.
So we've arrived at this by multiplying 5 × 4 × 3 × 2. Why start from 5? Because we initially had 5 letters: ABCDE. Why have four numbers in our multiplication? Because there were 4 empty spaces: _ _ _ _.
In general, you keep multiplying a decremented value starting from n, and do this k times: n × (n - 1) × ... × (n - k + 1).
The last value is (n - k + 1) because you are multiplying k values in total. From n to (n - k + 1) there are k values in total (inclusive).
We can test this with our n = 5 and k = 4 example. We said that the formula was 5 × 4 × 3 × 2. Now look at the general formula: indeed, we start from n = 5 and keep multiplying until we reach the number 5 - 4 + 1 = 2.
In your function's signature, n is setLength, k is comboLength. The implementation should be trivial with the above formulas, so I'm leaving this to the reader.
These are called permutations with and without repetition.

Why in two's complement (-1 >> 1) == -1 and not 0?

Note I think some commenters misunderstand my question that I don't understand integer division and floating point division - More clarification: I expected -1/2 == -1 >> 1 == 0, but in fact -1 >> 1 = -1.
I'm learning two's complement. I understand a special thing about bit shifting in two's complement's context is that right shifting needs to maintain the sign of the bit, such that right shifting a negative number should fill in 1 instead of 0. And left shifting should always fill 0. This is explained in the Wikipedia's article.
According to the article, the motivation behind this is to maintain the equivalency of bit shifting operation and the corresponding multiplication or division by 2. However, a special case I immediately noticed is -1. Under the above mentioned rule, -1>>1 does not equal to -1/2.
My question is how should I understand this? And what precautions should I take when applying bit shifts in optimization of multiplication and division?
Here's a C# (should be equivalent in other languages) code illustrating what I meant:
class Program
{
static void Main(string[] args)
{
foreach (int x in new[] { 0, 1, 2, 3, -1, -2, -3 })
{
int a = x >> 1;
int b = x / 2;
Console.WriteLine($"Number:{x}, x>>1: {a}, x/2: {b}");
}
}
}
This produces the output of:
Number:0, x>>1: 0, x/2: 0
Number:1, x>>1: 0, x/2: 0
Number:2, x>>1: 1, x/2: 1
Number:3, x>>1: 1, x/2: 1
Number:-1, x>>1: -1, x/2: 0
Number:-2, x>>1: -1, x/2: -1
Number:-3, x>>1: -2, x/2: -1
You should not use shift operatings in your code, if you are trying to do division. The optimizer is able to figure this out better than you can. Of course, if you really know what you are doing and you are using unsigned integers entirely and you are writing in assembly, go ahead. Until then, just use the normal math operators for doing normal math operations.
If you are asking why -1 >> 1 == -1, well that's easy. The value negative one looks like all ones in binary, or 0xFFFFFFFF in hex. Shift the bits to the right and shift-in in a new 1 to the empty hole on the left, and you are left with what you started !
The results are still consistent. The effect that a right shift by 1 has is division by 2 rounded down.
In the case of an odd positive value, the "extra" 0.5 gets dropped. In the case of an odd negative value, it goes the other way.
In the examples you give above, half of -1 is -0.5, rounded down to -1. Similarly, half of -3 is -1.5, rounded down to -2.
Why does -1 >> 1 == -1?
Whenever you shift, the machine must fill in a missing value. We'll use four bits just to keep things simple. When you shift left, the bit that must be replaced is the trailing bit:
0101 << 1 // equivalent of 5 * 2
101_ // This is filled in with a zero
1010 // 5 * 2 == 10
When you shift right, the leading bit must be replaced. But since the leading bit determines sign in signed 2s complement, we don't want to lose that sign (shifting left, or int dividing by some power of 2, should never cause a negative number to become positive or vice versa). So the replacement value is whatever the leading (sign) bit already was:
0111 >> 1 // equivalent of 7 intdiv 2
_011 // Signed, so this is filled in with a zero
0011 // 7 intdiv 2 == 3
1111 >> 1 // equivalent of -1 intdiv 2, kinda
_111 // Signed, so this is filled in with a 1
1111 // -1 intdiv 2 == -1
However, if this was unsigned representation, the leading bit would simply be filled in with a zero:
1111 >> 1 // equivalent of 15 intdiv 2
_111 // Unsigned, so this is filled in with a 0
0111 // 15 intdiv 2 == 7
Further reading: https://msdn.microsoft.com/en-us/library/336xbhcz.aspx
The Wiki article is wrong for c. This statement: These rules preserve the common semantics that left shifts multiply the number by two and right shifts divide the number by two. is not correct for c when looking at odd negative integers.
For integer division c uses round towards zero (or truncation toward zero as it is stated in the standard), i.e. if the real result is 1.5 the integer result will be 1. If the real result is -1.5 the integer result will be -1.
For c the standard doesn't specify what should happen to negative integers when doing a right shift - it is implementation-defined.
If your system uses two's complement right shift doesn't work the same way as division. In general shifting has nothing to do with rounding. However, if you want to look at a two's complement right shift as a division, you got to notice that it rounds towards minus infinity. That is: if the real result is 1.5 the integer result will be 1. If the real result is -1.5 the integer result will be -2.
Conclusion: Rigth shift is not the same as division by 2 for odd negative integers.
Your direct question:
-1 >> 1 is ??
If you consider right shift as a division by 2, the real result would be -0.5 but since it works like round towards minus infinity, the result will be rounded to -1
But as stated - right shift is not a division by 2. You have to look at the bit level.
At bit level it is simply because the bit pattern for -1doesn't change.
In two's complement -1 is an all-ones bit pattern, e.g.
int a = -1; // Pattern 11111111.11111111.11111111.11111111
when you right shift a two complements integer being -1 you simply get the same bit pattern and therefore the same value. You shift out a 1at LSB and shift in a 1 at MSB. So the binary pattern stays the same.
So what happens to -3:
int a = -3; // Pattern 11111111.11111111.11111111.11111101
a = a >> 1; // Pattern 11111111.11111111.11111111.11111110 = -2
Consider this case:
-1 = 0b11
-1 >> 1 => 0b11 >> 1 => 0b11 (Many 1s on the left) (= -1)
If you look back -3 >> 1 case (prepare your computer's calc in programmer's mode)
you should see 0b111101 >> 1 becomes 0b111110 (-2)

operator << in c# [duplicate]

This question already has answers here:
What does the operator "<<" mean in C#?
(9 answers)
Closed 7 years ago.
i couldn't understand this code in c#
int i=4
int[] s =new int [1<<i];
Console.WriteLine(s.length);
the ouput is 16
i don't know why the output like that?
bit shift operator
From documentation
If first operand is an int or uint
(32-bit quantity), the shift count is
given by the low-order five bits of
second operand.
If first operand is a long or ulong
(64-bit quantity), the shift count is
given by the low-order six bits of
second operand.
Note that i<<1 and i<<33 give the same
result, because 1 and 33 have the same
low-order five bits.
This will be the same as 2^( the actual value of the lower 5 bits ).
So in your case it would be 2^4=16.
I'm assuming you mean i in place of r...
<<n means "shift left by n* bits". Since you start with 1=binary 00...00001, if you shift left 4 times you get binary 00...10000 = 16 (it helps if you are familiar with binary arithmetic - otherwise "calc.exe" has a binary converter).
Each bit moves left n places, filling (on the right) with 0s. *=note that n is actually "mod 32" for int, so (as a corner case) 1 << 33 = 2, not 0 which you might expect.
There is also >> (right shift), which moves for the right, filling with 0 for uints and +ve ints, and 1 for -ve ints.
<< is the left shift operator
x << y
means shift x to the left by y bits.
3 is 0011, 3<<1 is 0110 which 6.
It's usually used to multiply by 2 (shifting to the left is multiplying by 2)
As already mentioned, << is the left shift operator. In your particular example, the array size is being defined as a power of 2. The value 1 shifted left by some number is going to be 1, 2, 4, 8, 16, ...

Why AND two numbers to get a Boolean?

I am working on a little Hardware interface project based on the Velleman k8055 board.
The example code comes in VB.Net and I'm rewriting this into C#, mostly to have a chance to step through the code and make sense of it all.
One thing has me baffled though:
At one stage they read all digital inputs and then set a checkbox based on the answer to the read digital inputs (which come back in an Integer) and then they AND this with a number:
i = ReadAllDigital
cbi(1).Checked = (i And 1)
cbi(2).Checked = (i And 2) \ 2
cbi(3).Checked = (i And 4) \ 4
cbi(4).Checked = (i And 8) \ 8
cbi(5).Checked = (i And 16) \ 16
I have not done Digital systems in a while and I understand what they are trying to do but what effect would it have to AND two numbers? Doesn't everything above 0 equate to true?
How would you translate this to C#?
This is doing a bitwise AND, not a logical AND.
Each of those basically determines whether a single bit in i is set, for instance:
5 AND 4 = 4
5 AND 2 = 0
5 AND 1 = 1
(Because 5 = binary 101, and 4, 2 and 1 are the decimal values of binary 100, 010 and 001 respectively.)
I think you 'll have to translate it to this:
i & 1 == 1
i & 2 == 2
i & 4 == 4
etc...
This is using the bitwise AND operator.
When you use the bitwise AND operator, this operator will compare the binary representation of the two given values, and return a binary value where only those bits are set, that are also set in the two operands.
For instance, when you do this:
2 & 2
It will do this:
0010 & 0010
And this will result in:
0010
0010
&----
0010
Then if you compare this result with 2 (0010), it will ofcourse return true.
Just to add:
It's called bitmasking
http://en.wikipedia.org/wiki/Mask_(computing)
A boolean only require 1 bit. In the implementation most programming language, a boolean takes more than a single bit. In PC this won't be a big waste, but embedded system usually have very limited memory space, so the waste is really significant. To save space, the booleans are packed together, this way a boolean variable only takes up 1 bit.
You can think of it as doing something like an array indexing operation, with a byte (= 8 bits) becoming like an array of 8 boolean variables, so maybe that's your answer: use an array of booleans.
Think of this in binary e.g.
10101010
AND
00000010
yields 00000010
i.e. not zero. Now if the first value was
10101000
you'd get
00000000
i.e. zero.
Note the further division to reduce everything to 1 or 0.
(i and 16) / 16 extracts the value (1 or 0) of the 5th bit.
1xxxx and 16 = 16 / 16 = 1
0xxxx and 16 = 0 / 16 = 0
And operator performs "...bitwise conjunction on two numeric expressions", which maps to '|' in C#. The '` is an integer division, and equivalent in C# is /, provided that both operands are integer types.
The constant numbers are masks (think of them in binary). So what the code does is apply the bitwise AND operator on the byte and the mask and divide by the number, in order to get the bit.
For example:
xxxxxxxx & 00000100 = 00000x000
if x == 1
00000x00 / 00000100 = 000000001
else if x == 0
00000x00 / 00000100 = 000000000
In C# use the BitArray class to directly index individual bits.
To set an individual bit i is straightforward:
b |= 1 << i;
To reset an individual bit i is a little more awkward:
b &= ~(1 << i);
Be aware that both the bitwise operators and the shift operators tend to promote everything to int which may unexpectedly require casting.
As said this is a bitwise AND, not a logical AND. I do see that this has been said quite a few times before me, but IMO the explanations are not so easy to understand.
I like to think of it like this:
Write up the binary numbers under each other (here I'm doing 5 and 1):
101
001
Now we need to turn this into a binary number, where all the 1's from the 1st number, that is also in the second one gets transfered, that is - in this case:
001
In this case we see it gives the same number as the 2nd number, in which this operation (in VB) returns true. Let's look at the other examples (using 5 as i):
(5 and 2)
101
010
----
000
(false)
(5 and 4)
101
100
---
100
(true)
(5 and 8)
0101
1000
----
0000
(false)
(5 and 16)
00101
10000
-----
00000
(false)
EDIT: and obviously I miss the entire point of the question - here's the translation to C#:
cbi[1].Checked = i & 1 == 1;
cbi[2].Checked = i & 2 == 2;
cbi[3].Checked = i & 4 == 4;
cbi[4].Checked = i & 8 == 8;
cbi[5].Checked = i & 16 == 16;
I prefer to use hexadecimal notation when bit twiddling (e.g. 0x10 instead of 16). It makes more sense as you increase your bit depths as 0x20000 is better than 131072.

Categories

Resources