Anonymous
Anonymous

Reputation: 557

How to work with the bits in a byte

I have a single byte which contains two values. Here's the documentation:

The authority byte is split into two fields. The three least significant bits carry the user’s authority level (0-5). The five most significant bits carry an override reject threshold. If these bits are set to zero, the system reject threshold is used to determine whether a score for this user is considered an accept or reject. If they are not zero, then the value of these bits multiplied by ten will be the threshold score for this user.

Authority Byte:

7 6 5 4 3 ......... 2 1 0
Reject Threshold .. Authority

I don't have any experience of working with bits in C#.

Can someone please help me convert a Byte and get the values as mentioned above?

I've tried the following code:

BitArray BA = new BitArray(mybyte); 

But the length comes back as 29 and I would have expected 8, being each bit in the byte.

-- Thanks for everyone's quick help. Got it working now! Awesome internet.

Upvotes: 6

Views: 10571

Answers (4)

dtb
dtb

Reputation: 217401

Instead of BitArray, you can more easily use the built-in bitwise AND and right-shift operator as follows:

byte authorityByte = ...

int authorityLevel = authorityByte & 7;
int rejectThreshold = authorityByte >> 3;

To get the single byte back, you can use the bitwise OR and left-shift operator:

int authorityLevel = ...
int rejectThreshold = ...

Debug.Assert(authorityLevel >= 0 && authorityLevel <= 7);
Debug.Assert(rejectThreshold >= 0 && rejectThreshold <= 31);

byte authorityByte = (byte)((rejectThreshold << 3) | authorityLevel);

Upvotes: 7

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 727047

To get a value of the five most significant bits in a byte as an integer, shift the byte to the right by 3 (i.e. by 8-5), and set the three upper bits to zero using bitwise AND operation, like this:

byte orig = ...
int rejThreshold = (orig >> 3) & 0x1F;
  • >> is the "shift right" operator. It moves bits 7..3 into positions 4..0, dropping the three lower bits.
  • 0x1F is the binary number 00011111, which has the upper three bits set to zero, and the lower five bits set to one. AND-ing with this number zeroes out three upper bits.

This technique can be generalized to get other bit patterns and other integral data types. You shift the bits that you want into the least-significant position, and apply a mask that "cuts out" the number of bits that you want. In some cases, shifting would not be necessary (e.g. when you get the least significant group of bits). In other cases, such as above, the masking would not be necessary, because you get the most significant group of bits in an unsigned type (if the type is signed, ANDing would be required).

Upvotes: 4

Simon Whitehead
Simon Whitehead

Reputation: 65087

Your use of the BitArray is incorrect. This:

BitArray BA = new BitArray(mybyte);

..will be implicitly converted to an int. When that happens, you're triggering this constructor:

BitArray(int length);

..therefore, its creating it with a specific length.

Looking at MSDN (http://msdn.microsoft.com/en-us/library/x1xda43a.aspx) you want this:

BitArray BA = new BitArray(new byte[] { myByte });

Length will then be 8 (as expected).

Upvotes: 7

Patryk Ćwiek
Patryk Ćwiek

Reputation: 14328

You're using the wrong constructor (probably).

The one that you're using is probably this one, while you need this one:

var bitArray = new BitArray(new [] { myByte } );

Upvotes: 3

Related Questions