Checking bits in a byte using for loop - c#

I was recently studying C# where i came across following for loop
// Display the bits within a byte.
using System;
class ShowBits {
static void Main() {
int t;
byte val;
val = 123;
for(t=128; t > 0; t = t/2) {
if((val & t) != 0)
Console.Write("1 ");
if((val & t) == 0)
Console.Write("0 ");
}
}
}
I am not able to understand that Why in doing t=t/2 in the incrementing/decrementing section of the for loop . plz explain

Decimal 128 is binary 10000000 - i.e. a mask for just the most significant bit of the byte. When you divide it by two, you get 01000000, i.e. the second most significant bit, etc.
Using & between the original value and the mask and just comparing with 0 indicates whether that bit is set in the original value.
Another alternative would be to shift the original value instead:
for (int i = 7; i >= 0; i--)
{
int shifted = val >> i;
// Take the bottom-most bit of the shifted value
Console.Write("{0} ", shifted & 1);
}

It's looping in decreasing powers of two and using that value in a mask.
(base 10): 128, 64, 32, 16, 8, 4, 2, 1
(base 2): 10000000, 01000000, 00100000, 00010000, 00001000, 00000100, 00000010, 00000001

128 is written as 10000000 in binary, so we check if the highest bit in a byte is on. Then we do t=t/2, which is t=128/2=64 which written as 01000000 in binary and so on. Any division shifts the one bit that is on one place to the right.

The t is used as a mask for the bits in val.
So it starts at 128, 10000000 in binary.
When it is divided by 2, it becomes 64 - or 01000000.
This goes until it reaches 0.
Then in each iteration, the '&' is used to mask the bits in val with the current bit in t.

Related

C# - What's the fastest way to convert a number to the smallest BitArray

I would like to convert a number to a BitArray, with the resulting BitArray only being as big as it needs to be.
For instance:
BitArray tooBig = new BitArray(new int[] { 9 });
results in a BitArray with a length of 32 bit, however for the value 9 only 4 bits are required. How can I create BitArrays which are only as long as they need to be? So in this example, 4 bits. Or for the number 260 I expected the BitArray to be 9 bits long
You can figure out all the bits first and then create the array by checking if the least significant bit is 1 or 0 and then right shifting until the number is 0. Note this will not work for negative numbers where the 32nd bit would be 1 to indicate the sign.
public BitArray ToShortestBitArray(int x)
{
var bits = new List<bool>();
while(x > 0)
{
bits.Add((x & 1) == 1);
x >>= 1;
}
return new BitArray(bits.ToArray());
}
Assuming you are working with exclusively unsigned integers, the number of bits you need is equal to the base 2 logarithm of the (number+1), rounded up.
Counting the bits is probably the easiest solution.
In JavaScript for example...
// count bits needed to store a positive number
const bits = (x, b = 0) => x > 0 ? bits(x >> 1, b + 1) : b;

C# possibilities tree from integers array

How can i build possibilities tree from integers array with C#? I need to make all possibles variants of array if in the every step delete one element from array.
example if we have array from three integers [1,2,3] then tree should looks like this: tree view
I would approach this as a binary arithmetic problem:
static void Main(string[] args)
{
int[] arr = { 1, 2, 3 };
PickElements(0, arr);
}
static void PickElements<T>(int depth, T[] arr, int mask = -1)
{
int bits = Math.Min(32, arr.Length);
// keep just the bits from mask that are represented in arr
mask &= ~(-1 << bits);
if (mask == 0) return;
// UI: write the options
for (int i = 0; i < depth; i++ )
Console.Write('>'); // indent to depth
for (int i = 0; i < arr.Length; i++)
{
if ((mask & (1 << i)) != 0)
{
Console.Write(' ');
Console.Write(arr[i]);
}
}
Console.WriteLine();
// recurse, taking away one bit (naive and basic bit sweep)
for (int i = 0; i < bits; i++)
{
// try and subtract each bit separately; if it
// is different, recurse
var childMask = mask & ~(1 << i);
if (childMask != mask) PickElements(depth + 1, arr, childMask);
}
}
For a TreeView, simply replace the Console.Write etc with node creation, presumably passing the parent node in (and down) as part of the recursion (in place of depth, perhaps).
To see what this is doing, consider the binary; -1 is:
11111111111111...111111111111111
we then look at bits, which we derive from the array length, and find to be 3 in this example. We only need to look at 3 bits, then; the line:
~(-1 << bits)
computes a mask for this, because:
-1 = 1111111....1111111111111
(-1 << 3) = 1111111....1111111111000 (left-shift back-fills with 0)
~(-1 << 3) = 0000000....0000000000111 (binary inverse)
we then apply this to our input mask, so we're only ever looking at the least significant 3 bits, via mask &= .... If that turns out to be zero, we've run out of things to do, so stop recursing.
The UI update is simple enough; we just scan over the 3 bits that we care about, checking whether the current bit is "on" for our mask; 1 << i creates a mask with just the "i-th set bit"; the & and != 0 checks whether that bit is set. If it is, we include the element in the output.
Finally, we need to start taking away bits, to look at the sub-tree; we could probably be more sophisticated about this, but I chose just to scan all the bits and try them - worst case this is 32 bit tests per level, which is nothing. As before, 1 << i creates a mask of just the "i-th set bit". This time we want to disable that bit, so we "negate" and "and" via mask & ~(...). It is possible that this bit was already disabled, so the childMask != mask check ensures we only actually recurse when we have disabled a bit that was previously enabled.
The end result is that we end up with the masks being successively:
11..1111111111111111 (special case for first call; all set)
110 (first bit disabled)
100 (first and second bits disabled)
010 (first and third bits disabled)
101 (second bit disabled)
100 (second and first bits disabled)
001 (second and third bits disabled)
011 (third bit disabled)
010 (third and first bits disabled)
001 (third and second bits disabled)
Note that for a simpler combination example, it would be possible to just iterate in a single for, using the bits to pick elements; however, I've done it a recursive way because we need to build a tree of successive subtractions, rather than just flat possibilities in no particular order.

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.
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);
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).
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).
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 } );

Number of unset bit left of most significant set bit?

Assuming the 64bit integer 0x000000000000FFFF which would be represented as
00000000 00000000 00000000 00000000
00000000 00000000 >11111111 11111111
How do I find the amount of unset bits to the left of the most significant set bit (the one marked with >) ?
In straight C (long long are 64 bit on my setup), taken from similar Java implementations: (updated after a little more reading on Hamming weight)
A little more explanation: The top part just sets all bit to the right of the most significant 1, and then negates it. (i.e. all the 0's to the 'left' of the most significant 1 are now 1's and everything else is 0).
Then I used a Hamming Weight implementation to count the bits.
unsigned long long i = 0x0000000000000000LLU;
i |= i >> 1;
i |= i >> 2;
i |= i >> 4;
i |= i >> 8;
i |= i >> 16;
i |= i >> 32;
// Highest bit in input and all lower bits are now set. Invert to set the bits to count.
i=~i;
i -= (i >> 1) & 0x5555555555555555LLU; // each 2 bits now contains a count
i = (i & 0x3333333333333333LLU) + ((i >> 2) & 0x3333333333333333LLU); // each 4 bits now contains a count
i = (i + (i >> 4)) & 0x0f0f0f0f0f0f0f0fLLU; // each 8 bits now contains a count
i *= 0x0101010101010101LLU; // add each byte to all the bytes above it
i >>= 56; // the number of bits
printf("Leading 0's = %lld\n", i);
I'd be curious to see how this was efficiency wise. Tested it with several values though and it seems to work.
Based on: http://www.hackersdelight.org/HDcode/nlz.c.txt
template<typename T> int clz(T v) {int n=sizeof(T)*8;int c=n;while (n){n>>=1;if (v>>n) c-=n,v>>=n;}return c-v;}
If you'd like a version that allows you to keep your lunch down, here you go:
int clz(uint64_t v) {
int n=64,c=64;
while (n) {
n>>=1;
if (v>>n) c-=n,v>>=n;
}
return c-v;
}
As you'll see, you can save cycles on this by careful analysis of the assembler, but the strategy here is not a terrible one. The while loop will operate Lg[64]=6 times; each time it will convert the problem into one of counting the number of leading bits on an integer of half the size.
The if statement inside the while loop asks the question: "can i represent this integer in half as many bits", or analogously, "if i cut this in half, have i lost it?". After the if() payload completes, our number will always be in the lowest n bits.
At the final stage, v is either 0 or 1, and this completes the calculation correctly.
If you are dealing with unsigned integers, you could do this:
#include <math.h>
int numunset(uint64_t number)
{
int nbits = sizeof(uint64_t)*8;
if(number == 0)
return nbits;
int first_set = floor(log2(number));
return nbits - first_set - 1;
}
I don't know how it will compare in performance to the loop and count methods that have already been offered because log2() could be expensive.
Edit:
This could cause some problems with high-valued integers since the log2() function is casting to double and some numerical issues may arise. You could use the log2l() function that works with long double. A better solution would be to use an integer log2() function as in this question.
// clear all bits except the lowest set bit
x &= -x;
// if x==0, add 0, otherwise add x - 1.
// This sets all bits below the one set above to 1.
x+= (-(x==0))&(x - 1);
return 64 - count_bits_set(x);
Where count_bits_set is the fastest version of counting bits you can find. See https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel for various bit counting techniques.
I'm not sure I understood the problem correctly. I think you have a 64bit value and want to find the number of leading zeros in it.
One way would be to find the most significant bit and simply subtract its position from 63 (assuming lowest bit is bit 0). You can find out the most significant bit by testing whether a bit is set from within a loop over all 64 bits.
Another way might be to use the (non-standard) __builtin_clz in gcc.
I agree with the binary search idea. However two points are important here:
The range of valid answers to your question is from 0 to 64 inclusive. In other words - there may be 65 different answers to the question. I think (almost sure) all who posted the "binary search" solution missed this point, hence they'll get wrong answer for either zero or a number with the MSB bit on.
If speed is critical - you may want to avoid the loop. There's an elegant way to achieve this using templates.
The following template stuff finds the MSB correctly of any unsigned type variable.
// helper
template <int bits, typename T>
bool IsBitReached(T x)
{
const T cmp = T(1) << (bits ? (bits-1) : 0);
return (x >= cmp);
}
template <int bits, typename T>
int FindMsbInternal(T x)
{
if (!bits)
return 0;
int ret;
if (IsBitReached<bits>(x))
{
ret = bits;
x >>= bits;
} else
ret = 0;
return ret + FindMsbInternal<bits/2, T>(x);
}
// Main routine
template <typename T>
int FindMsb(T x)
{
const int bits = sizeof(T) * 8;
if (IsBitReached<bits>(x))
return bits;
return FindMsbInternal<bits/2>(x);
}
Here you go, pretty trivial to update as you need for other sizes...
int bits_left(unsigned long long value)
{
static unsigned long long mask = 0x8000000000000000;
int c = 64;
// doh
if (value == 0)
return c;
// check byte by byte to see what has been set
if (value & 0xFF00000000000000)
c = 0;
else if (value & 0x00FF000000000000)
c = 8;
else if (value & 0x0000FF0000000000)
c = 16;
else if (value & 0x000000FF00000000)
c = 24;
else if (value & 0x00000000FF000000)
c = 32;
else if (value & 0x0000000000FF0000)
c = 40;
else if (value & 0x000000000000FF00)
c = 48;
else if (value & 0x00000000000000FF)
c = 56;
// skip
value <<= c;
while(!(value & mask))
{
value <<= 1;
c++;
}
return c;
}
Same idea as user470379's, but counting down ...
Assume all 64 bits are unset. While value is larger than 0 keep shifting the value right and decrementing number of unset bits:
/* untested */
int countunsetbits(uint64_t val) {
int x = 64;
while (val) { x--; val >>= 1; }
return x;
}
Try
int countBits(int value)
{
int result = sizeof(value) * CHAR_BITS; // should be 64
while(value != 0)
{
--result;
value = value >> 1; // Remove bottom bits until all 1 are gone.
}
return result;
}
Use log base 2 to get you the most significant digit which is 1.
log(2) = 1, meaning 0b10 -> 1
log(4) = 2, 5-7 => 2.xx, or 0b100 -> 2
log(8) = 3, 9-15 => 3.xx, 0b1000 -> 3
log(16) = 4 you get the idea
and so on...
The numbers in between become fractions of the log result. So typecasting the value to an int gives you the most significant digit.
Once you get this number, say b, the simple 64 - n will be the answer.
function get_pos_msd(int n){
return int(log2(n))
}
last_zero = 64 - get_pos_msd(n)

Why does the BitConverter return Bytes and how can I get the bits then?

As input I get an int (well, actually a string I should convert to an int).
This int should be converted to bits.
For each bit position that has a 1, I should get the position.
In my database, I want all records that have an int value field that has this position as value.
I currently have the following naive code that should ask my entity(holding the databaseValue) if it matches the position, but obviously doesn't work correctly:
Byte[] bits = BitConverter.GetBytes(theDatabaseValue);
return bits[position].equals(1);
Firstly, I have an array of byte because there apparantly is no bit type. Should I use Boolean[] ?
Then, how can I fill this array?
Lastly, if previous statements are solved, I should just return bits[position]
I feel like this should somehow be solved with bitmasks, but I don't know where to start..
Any help would be appreciated
Your feeling is correct. This should be solved with bitmasks. BitConverter does not return bits (and how could it? "bits" isn't an actual data type), it converts raw bytes to CLR data types. Whenever you want to extract the bits out of something, you should think bitmasks.
If you want to check if a bit at a certain position is set, use the & operator. Bitwise & is only true if both bits are set. For example if you had two bytes 109 and 33, the result of & would be
0110 1101
& 0010 0001
-----------
0010 0001
If you just want to see if a bit is set in an int, you & it with a number that has only the bit you're checking set (ie 1, 2, 4, 8, 16, 32 and so forth) and check if the result is not zero.
List<int> BitPositions(uint input) {
List<int> result = new List<int>();
uint mask = 1;
int position = 0;
do {
if (input & mask != 0) {
result.Add(position);
}
mask <<= 1;
position++;
} while (mask != 0);
return result;
}
I suspect BitArray is what you're after. Alternatively, using bitmasks yourself isn't hard:
for (int i=0; i < 32; i++)
{
if ((value & (1 << i)) != 0)
{
Console.WriteLine("Bit {0} was set!", i);
}
}
Do not use Boolean. Although boolean has only two values, it is actually stored using 32 bits like an int.
EDIT: Actually, in array form Booleans will be packed into bytes, not 4 bytes.

Categories

Resources