C#, bits & bytes - How do I retrieve bit values from a byte? - c#

I'm reading some values from a single byte. I'm told in the user-manual that this one byte contains 3 different values. There's a table that looks like this:
I interpret that has meaning precision takes up 3 bits, scale takes up 2 and size takes up 3 for a total of 8 (1 byte).
What I'm not clear on is:
1 - Why is it labeled 7 through 0 instead of 0 through 7 (something to do with significance maybe?)
2 - How do I extract the individual values out of that one byte?

It is customary to number bits in a byte according to their significance: bit x represents 2^x. According to this numbering scheme, the least significant bit gets number zero, the next bit is number one, and so on.
Getting individual bits requires a shift and a masking operation:
var size = (v >> 0) & 7;
var scale = (v >> 3) & 3;
var precision = (v >> 5) & 7;
Shift by the number of bits to the right of the rightmost portion that you need to get (shifting by zero is ignored; I added it for illustration purposes).
Mask with the highest number that fits in the number of bits that you would like to get: 1 for one bit, 3 for two bits, 7 for three bits, 2^x-1 for x bits.

You can do shifts and masks, or you can use the BitArray class: http://msdn.microsoft.com/en-us/library/system.collections.bitarray.aspx
Example with BitVector32:
BitVector32 bv = new BitVector32(0);
var size = BitVector32.CreateSection(7);
var scale = BitVector32.CreateSection(3, size);
var precision = BitVector32.CreateSection(7, scale);
bv[size] = 5;
bv[scale] = 2;
bv[precision] = 4;
LINQPad output:

Potayto, potahto.
You'd use shifts and masks to flatten out the undesired bits, like such:
byte b = something; // b is our byte
int size = b & 0x7;
int scale = (b >> 3) & 0x3;
int position = (b >> 5) & 0x7;

1. Yes, the most significant bit is usually written first. The left-most bit is labeled 7 because when the byte is interpreted as an integer, that bit has value 27 (= 128) when it is set.
This is completely natural and is in fact is exactly the same as how you write decimal numbers (most significant digit first). For example, the number 356 is (3 x 102) + (5 x 101) + (6 x 100).
2. For completion, as mentioned in other answers you can extract the individual values using the bit shift and bitwise-and operators as follows:
int size = x & 7;
int scale = (x >> 3) & 3;
int precision = (x >> 5) & 7;
Important note: this assumes that the individual values are to be interpreted as positive integers. If the values could be negative then this won't work correctly. Given the names of your variables, this is unlikely to be a problem here.

You can do this via bitwise arithmetic:
uint precision = (thatByte & 0xe0) >> 5,
scale = (thatByte & 0x18) >> 3,
size = thatByte & 7;

Related

Casting Double to Int

I found an example for casting. When I try to cast long to int, I get the following output.
long e = 10;
int x = (int) e ;
WriteLine($"e is {e:N0} and x is {x:N0} ");
e = long.MaxValue;
x = (int) e;
WriteLine($"e is {e:N0} and x is {x:N0} ");
e = 5_000_000_000;
x = (int) e;
WriteLine($"e is {e:N0} and x is {x:N0} ");
For case 1, 10 can fit into int, so there is no issue,
For case 2, value -> long max value won't fit in int, so the output is 1
For case 3, value = 5_000_000_000, which also won't fit in int, so it should output 1, but it outputs 705,032,704 Can anyone explain why we are getting this value?
Output of above code is :
e is 10 and x is 10
e is 9,223,372,036,854,775,807 and x is -1
e is 5,000,000,000 and x is 705,032,704
The reason is that under the covers we're working in binary, and when we cast to a smaller binary value we take as many binary bits as we can from the old value to create our new value.
5,000,000,000 in binary is 100101010000001011111001000000000. If we put this in 32 bits (the size of an int) we get 00101010000001011111001000000000. We just lose the leading 1 because the original number is 33 bits. If we convert that to decimal it is 705032704.
This converter is useful to see this.
Edit:
For long.MaxValue becoming -1 we have to understand how we represent negative numbers in binary. We use the leftmost bit. If it's zero the number is positive, if it's one the number is negative. So for a 64-bit number the maximum positive value is 0 plus 63 1's: 0111111111111111111111111111111111111111111111111111111111111111. If we have 64 1's the number is negative, in fact it's -1 by the way negative numbers work, and obviously that isn't the maximum possible value.
Now if we take the rightmost 32 bits of that big binary number we get 32 1's in a row, and that is -1. The BBC has quite a good explanation of negative number representations in binary.
You need to look at (int)e operation like (e % int.MaxValue), so in your example you get the following:
long.MaxValue % int.MaxValue = 1
5000000000 % int.MaxValue = 705032704

how do I extract the 5th bit of a byte in c#

If I have the decimal 12, its representation in binary is 00001100. How do I extract the fifth bit, which in this case is 1? I tried shifting left by 4 and AND-ing with 1 but this is not correct. Can someone tell me what I am doing wrong?
player = low << 4 & 1;
You actually want to obtain 3d bit (starting from the right end):
00001100
^
3d from the right end (bits are zero based)
All you have to do is to get rid of 3 lower bits (100) with a help of >> and check the next bit:
// 1 if 3d bit is set, 0 otherwise
player = (low >> 3) & 1;
Or if you have number 5 - index from the left end and assuming low being byte:
player = (low >> (sizeof(byte) * 8 - 5)) & 1;
You need to left shift the One and & with your variable.
player = (1 << 4) & low;
This will give you the 5th binary digit with trailing zeros.
player = ((1 << 4) & low) >> 4;
This gives the exact 5th binary Digit, removing the Trailing Zeros.
Instead of shifting bits, you can simply use a bitwise AND. As others said, you are looking at the 3rd bit from the right (zero-based), in other words, at the bit that represents 2^3.
player = (low & 8) / 8;
A more generic solution would be
private int GetBit(int number, int bit) => (number & (1 << bit)) / (1 << bit);
Note: This does require casting your decimal to int since & doesn't work with decimals.

How to change bits into binary integer if the bits start to count from left to right in C#?

I want to change the bits into a 16 bits integer in a certain position but the position of the bits its given from left to right. How to do it ?
Here is an example: I have to change the bits in given position to "1".
int a = 27991; // binary its "01101101 01010111"
int position1 = 12; // this position means i have to change "01101101 0101**0**111"
int position2 = 1; // this position means i have to change "0**1**101101 01010111"
I hope you understood me and someone can help a little.
You can make a mask that has the leftmost bit, and then shift it right positionX times to make the proper mask:
int topBit = 1<<16; // 10000000 00000000
int mask = topBit >> position1;
Now you can use mask to set or to clear the target bit, like this:
int b = a | mask; // Set 12-th bit to 1
int c = a & ~mask; // Set 12-th bit to 0

C# math question: smallest power of 2 bigger than X?

public int CalcBrackets(int teamCount)
{
int positions = 1;
while (positions < teamCount)
positions *= 2;
return positions;
}
I want the smallest number that is a power of 2 and bigger or equal than teamCount. Is this really the best way to do it? It sure looks horrible :(
If you need to calculate the least power of 2 (not the multiple) smaller then teamCount, then possibly it is the best way. Taking logarithm is a costy operation and can take more time then a simple cycle.
upd
Here is an algorithm (C++) using bitwise operations (http://aggregate.org/MAGIC/, section Next Largest Power of 2)
unsigned int nlpo2(unsigned int x)
{
x--; // comment out to always take the next biggest power of two, even if x is already a power of two
x |= (x >> 1);
x |= (x >> 2);
x |= (x >> 4);
x |= (x >> 8);
x |= (x >> 16);
return (x+1);
}
First, it sets all relevant bits of the number to ones (for example, 0x3ff) and then increments it (0x400) to get the power of two.
That while loop doesn't go over multiples of two, but rather powers of two.
If u really need the multiple just add 1, divide by 2 to get the half part and then multiply back by two:
return ((teamCount+1)/2)*2
so that if it was even then you obtain back the same nuber, while if it was odd, since you add 1 and then divide, you get the next even number.
Smallest multiple
return (teamCount % 2 == 0 ? teamCount : teamCount + 1);
Smallest power, you can take the log. Something like
2 ** (ceil(log_2(teamCount)))
For suitable ceil and log_2 functions. Your technique is fine though.
this way is simple enough:
if (teamCount % 2 == 0)
return teamCount;
else
return (teamCount + 1);
Not bigger smaller and if you mean multiple 2*2*2*2* log aritm best way that is use logaritma function in base 2 and round result to lower base.That is if team count equals 35 log 2 base 35 gives you 5,xxx round it to 5.

C# modulus operator

I can write the program
int a = 3;
int b = 4;
Console.WriteLine(a % b);
The answer I get is 3. How does 3 mod 4 = 3???
I can't figure out how this is getting computed this way.
I wasn't quite sure what to expect,
but I couldn't figure out how the
remainder was 3.
So you have 3 cookies, and you want to divide them equally between 4 people.
Because there are more people than cookies, nobody gets a cookie (quotient = 0) and you've got a remainder of 3 cookies for yourself. :)
Because the remainder of 3 / 4 = 3.
http://en.wikipedia.org/wiki/Modulo_operator
3 mod 4 is the remainder when 3 is divided by 4.
In this case, 4 goes into 3 zero times with a remainder of 3.
I found the accepted answer confusing and misleading.
Modulus is NOT the same as modern division that returns a ratio of dividend and divisor. This is often expressed as a decimal quotient that includes the remainder in the quotient. That is what trips people up.
Modulus is just the remainder in division before its used in a decimal quotient.
Example: The division of two numbers is often expressed as a decimal number (quotient). But the result of the division of say, 1/3, can also be expressed in whole numbers as "0 with a remainder of 1". But that form of quotient is not very helpful in modern math, so a decimal value or the ratio of the two numbers is often what we see returned in modern calculators.
1 / 3 = .333333333......
But modulus does not work that way. It ignores the decimal quotient value or ratio returned from division, takes the quotient expression of "0 with a remainder of 1" in 1/3, and extracts the 1 or remainder that was returned from that division. It just strips out the remainder from the quotient and spits back the remainder of division before its converted to a decimal. Below is how modulus works...
1 % 3 = 1
As such, a better way of describing Modulus is to say it is what is left over as an integer (remainder) in the first number (dividend) after dividing the second number (divisor) into it as many times as possible.
1 % 1 = 0 because after dividing 1 into 1, one time, there's nothing left
2 % 1 = 0 because after dividing 1 into 2, two times, there's nothing left
1 % 2 = 1 because 2 won't go into 1, so 1 is left
These whole number remainders returned by modulus (modular math) are useful in software programs in extracting the day of a week, creating alternating sequences, finding if a number is even or odd, etc.
I already think that the user may have understood the answers. Because there are so many good programmer.. in simple wording % tells you the reminder after dividing with your own integer.
e.g.
int a = int.Parse(Console.ReadLine());
int b = a % 2;
Now your input 13, it will give 1, because after diving 13 by 2 remainder is 1 in simple mathematics. Hope you got that.
As explained by others, but if you don't want to use the "mod" operator. Here is the equation to figure out the remainder of "a" divided by "n"
a-(n* int(a/n))
Another "as explained by others", but if you're curious about several more ways to do modulus (or use an alternative method), you can read this article which benchmarks a few different ways.
Basically, the fastest way is the good old fashioned modulus operator, similar to:
if (x % threshold == some_value)
{
//do whatever you need to
}
Perhaps the C# implementation is self explanatory -
static void Main(string[] args)
{
int a = 3;
int b = 4;
Console.WriteLine(a % b);
Console.WriteLine(MOD(a,b));
Console.ReadKey();
}
public static int MOD(int a, int b)
{
int i, j, k;
i = a / b;
j = i * b;
k = a - j;
return k;
}

Categories