how to loop through the digits of a binary number? - c#

I have a binary number 1011011, how can I loop through all these binary digits one after the other ?
I know how to do this for decimal integers by using modulo and division.

int n = 0x5b; // 1011011
Really you should just do this, hexadecimal in general is much better representation:
printf("%x", n); // this prints "5b"
To get it in binary, (with emphasis on easy understanding) try something like this:
printf("%s", "0b"); // common prefix to denote that binary follows
bool leading = true; // we're processing leading zeroes
// starting with the most significant bit to the least
for (int i = sizeof(n) * CHAR_BIT - 1; i >= 0; --i) {
int bit = (n >> i) & 1;
leading |= bit; // if the bit is 1, we are no longer reading leading zeroes
if (!leading)
printf("%d", bit);
}
if (leading) // all zero, so just print 0
printf("0");
// at this point, for n = 0x5b, we'll have printed 0b1011011

You can use modulo and division by 2 exactly like you would in base 10. You can also use binary operators, but if you already know how to do that in base 10, it would be easier if you just used division and modulo

Expanding on Frédéric and Gabi's answers, all you need to do is realise that the rules in base 2 are no different to in base 10 - you just need to do your division and modulus with a divisor 2 instead of 10.
The next step is simply to use number >> 1 instead of number / 2 and number & 0x1 instead of number % 2 to improve performance. Mind you, with modern optimising compilers there's probably no difference...

Use an AND with increasing powers of two...

In C, at least, you can do something like:
while (val != 0)
{
printf("%d", val&0x1);
val = val>>1;
}

To expand on #Marco's answer with an example:
uint value = 0x82fa9281;
for (int i = 0; i < 32; i++)
{
bool set = (value & 0x1) != 0;
value >>= 1;
Console.WriteLine("Bit set: {0}", set);
}
What this does is test the last bit, and then shift everything one bit.

If you're already starting with a string, you could just iterate through each of the characters in the string:
var values = "1011011".Reverse().ToCharArray();
for(var index = 0; index < values.Length; index++) {
var isSet = (Boolean)Int32.Parse(values[index]); // Boolean.Parse only works on "true"/"false", not 0/1
// do whatever
}

byte input = Convert.ToByte("1011011", 2);
BitArray arr = new BitArray(new[] { input });
foreach (bool value in arr)
{
// ...
}

You can simply loop through every bit. The following C like pseudocode allows you to set the bit number you want to check. (You might also want to google endianness)
for()
{
bitnumber = <your bit>
printf("%d",(val & 1<<bitnumber)?1:0);
}
The code basically writes 1 if the bit it set or 0 if not. We shift the value 1 (which in binary is 1 ;) ) the number of bits set in bitnumber and then we AND it with the value in val to see if it matches up. Simple as that!
So if bitnumber is 3 we simply do this
00000100 ( The value 1 is shifted 3 left for example)
AND
10110110 (We check it with whatever you're value is)
=
00000100 = True! - Both values have bit 3 set!

Related

Shift bits of an integer only if the number of bits of its binary presentation is greater then given value

I need to shift the bits of an integer to the right only if the number of bits is greater then a certain number. For the example Lets take 10.
If the integer is 818 the then binary representation of the integer is 1100110010, In that case i do nothing.
If the Integer is 1842 the binary representation of the integer is 11100110010 which is greater then 10 by one, So i need to shift one bit to the right(Or setting bit at index 10 to 0 which gives the same result as far as i know, Maybe im wrong).
What i did until now is make an integer array of ones and zeros represent the int, But i`m sure there is more elegant way of doing this
int y = 818;
string s = Convert.ToString(y, 2);
int[] bits = s.PadLeft(8, '0')
.Select(c => int.Parse(c.ToString()))
.ToArray();
if (bits.Length > 10)
{
for (int i = 10; i < bits.Length; i++)
{
bits[i] = 0;
}
}
I also tried to do this:
if(bits.Length > 10){ y = y >> (bits.Length - 10)}
but for some reason i got 945 (1110110001) when the input was 1891 (11101100011)
There's no need to do this with strings. 2 to the power of 10 has 11 binary digits, so
if (y >= Math.Pow(2, 10))
{
y = y >> 1;
}
seems to do what you want.

How to flip bits in C#?

I have a binary number in the form of a string as
string input = "10110101101";
Now I need to flip (0 to 1 and 1 to 0) the first 3 bits of it.
The resultant output will be 01010101101
How to do so in C#?
This works:
string input = "10110101101";
string output =
new string(
input
.Take(3)
.Select(c => c == '0' ? '1' : '0')
.Concat(input.Skip(3))
.ToArray());
It gives the result:
01010101101
Another alternative is to do this:
string input = "10110101101";
string flips = "11100000000";
int value = Convert.ToInt32(input, 2) ^ Convert.ToInt32(flips, 2);
string output = Convert.ToString(value, 2).PadLeft(input.Length, '0');
Make StringBuilder out of your string, flip the initial three characters, and convert StringBuilder back to string:
var sb = new StringBuilder(input);
Debug.Assert(sb.Length >= 3);
for (int i = 0 ; i != 3 ; i++) {
sb[i] = sb[i] == '0' ? '1' : '0';
}
var res = sb.ToString();
There are various "smart" ways of flipping the characters without conditional, but given that the number is in a string making the flip smarter wouldn't buy you much CPU cycles.
Demo.
An alternate way using Convert.ToInt32, Convert.ToString (which otherwise unknown and unused), and bitwise-XOR
string input = "10110101101";
int flipNo = 3;
int output = Convert.ToInt32(input, 2);
for (int i = input.Length - 1; i >= input.Length - flipNo; --i)
output ^= 1 << i;
Simply use the output, or if you want to display the output in string, you could do:
string display = Convert.ToString(output, 2).PadLeft(input.Length, '0');
Suppose you are given an array a of size N. The elements of the array are a[0], a[1], ... a[N - 1], where each a is either 0 or 1. You can perform one transformation on the array: choose any two integers L, and R, and flip all the elements between (and including) the Lth and Rth bits. In other words, L and R represent the left-most and the right-most index demarcating the boundaries of the segment whose bits you will decided to flip. ('Flipping' a bit means, that a 0 is transformed to a 1 and a 1 is transformed to a 0.)
What is the maximum number of '1'-bits (indicated by S) which you can obtain in the final bit-string?
Input Format:
The first line has a single integerN
The next N lines contains the N elements in the array, a[0], a[1], ... a[N - 1], one per line.
For instance consider
1 ≤ N ≤ 100,000.
d can be either 0 or 1. It cannot be any other integer.
0 ≤ L ≤ R < N
Sample Input:
810010010
Sample Output:
6
Explanation:
We can get a maximum of 6 ones in the given binary array by performing either of the following operations:
Flip [1, 5] ⇒ 1 1 1 0 1 1 1 0
or
Flip [1, 7] ⇒ 1 1 1 0 1 1 0 1
Solution:
The bits array will only contain 0 and 1. So we can view 0 as -1, then the task is to find the
minimum sum of subArray in bits, which is the subArray that has the largest value of
(number of 0s- number of 1s).
We can use the same method as find maximum sum subArray to find minimum sum subArray. Before that,
we need to traverse bits first to get original number of 1s. Suppose the minimum sum is minRes and
original number of 1s is currentOne. Then minRes should be a negative number, so return currentOne-minRes.
Edge case:
All edge cases can be handled using the above method. If all elements are 0, then we add all -1 together.
If all elements are 1, then the minRes should be 0, which means we do not do flip any bit.
Time: O(n) Space: O(1)
using System;
using System.Linq;
public class Test
{
public static int FlippingBits(int[] bits){
int currentOne = 0; //original number of 1s in bits
foreach(int i in bits){
if(i==1)
currentOne++;
}
int minRes = MinSubArray(bits); //minRes is negative number
return currentOne-minRes;
}
//find the min sum of subArray in bits
private static int MinSubArray(int[] bits){
int minRes = 0, minHere=0;
foreach(int i in bits){
if(i==0)
minHere-=1;
else
minHere+=1;
minHere = Math.Min(minHere,0); //keep minHere<=0
minRes = Math.Min(minHere, minRes);
}
return minRes; //-minRes is the number of 1 can be added to the array after flipping
}
public static void Main()
{
int num = int.Parse(Console.ReadLine());
for(int i=0;i<num;i++){
string[] input = Console.ReadLine().Split();
int[] bits = input.Select(y=>int.Parse(y)).ToArray();
Console.WriteLine(FlippingBits(bits));
}
}
}
The solution is quite simple; just XOR the values with 1 (0 works too).
Steps:
For the first x characters, XOR with 1 and get the return value (simple for loop).
Replace the old string with the new one.

C# How to remove the n-th bit in integer?

I am trying to find a way to remove a bit from an integer. The solution must not use string operations.
For example, I have the number 27, which is 11011 in binary.
I want to remove the third bit so it leaves me with 1011.
Or we have 182 (10110110), remove the 6th bit so the result is 1110110 (which is 118). I am trying to think of the algorithm how to do that, but so far no luck, and I can't find useful information on the internet.
I know how to use bitwise operators and how to extract or manipulate bits in integers (change values, exchange values etc), but I don't know how to 'remove' a certain bit.
I am not looking for code, just the logic of the operation. If anyone could help me, that would be awesome!
Regards,
Toni
No problem, just decompose the number into the "upper part" and the "lower part", and put them together without the middle bit that now disappeared.
Not tested:
uint upper = x & 0xFFFFFFF0;
uint lower = x & 7;
return (upper >> 1) | lower;
More generally: (also not tested)
uint upper = x & (0xFFFFFFFE << n);
uint lower = x & ((1u << n) - 1);
return (upper >> 1) | lower;
In order to do this you need two bit masks and a shift.
The first bit mask gives you the portion of the number above bit n, exclusive of the n-th bit. The mask is constructed as follows:
var top = ~((1U<<(n+1))-1); // 1111 1111 1000 000, 0xFF80
The second bit mask gives you the portion of the number below bit n, exclusive of the n-th bit:
var bottom = (1U<<n)-1; // 0000 0000 0011 1111, 0x003F
Comments above show the values for your second example (i.e. n == 6)
With the two masks in hand, you can construct the result as follows:
var res = ((original & top)>>1) | (original & bottom);
Demo.
You could use the following approach:
int value = 27;
string binary = Convert.ToString(value, 2);
binary = binary.Remove(binary.Length-3-1,1); //Remove the exact bit, 3rd in this case
int newValue = Convert.ToInt32(binary, 2);
Console.WriteLine(newValue);
Hope it helps!
int Place = 7;
int TheInt = 182;
string binary = Convert.ToString(TheInt, 2);
MessageBox.Show(binary.Remove(binary.Length - Place, 1));
Here is a version that needs slightly fewer operations than the solution by harold:
x ^ (((x >> 1) ^ x) & (0xffffffff << n));
The idea is that below n, bits are xored with zero, leaving them unchanged, while from n and above the two x xored cancel each other out, leaving x >> 1.
int a = 27;//int= 4byte equal to 32 bit
string binary = "";
for (int i = 0; i < 32; i++)
{
if ((a&1)==0)//if a's least significant bit is 0 ,add 0 to str
{
binary = "0" + binary;
}
else//if a's least significant bit is 1 ,add 1 to str
{
binary = "1" + binary;
}
a = a >> 1;//shift the bits left to right and delete lsb
//we are doing it for 32 times because integer have 32 bit.
}
Console.WriteLine("Integer to Binary= "+binary);
//Now you can operate the string(binary) however you want.
binary = binary.Remove(binary.Length-4,1);//remove 4st bit from str

Bits needed to change one number to another

Say I have two positive numbers a and b. How many bits must be inverted in order to convert a into b ?
I just want the count and not the exact position of the differing bits.
Lets assume a = 10 ( 1010 ) and b = 8 ( 1000 ). In this case the number of bits that should be inverted equals 1.
Any generalised algorithm?
The solution is simple
Step 1 ) Compute a XOR b
Step 2 ) Count the number of set bits in the result
Done!
int a = 10;
int b = 8;
int c = a ^ b; //xor
int count = 0;
while (c != 0)
{
if ((c & 1) != 0)
count++;
c = c >> 1;
}
return count;
changeMask = a XOR b
bitsToChange = 0
while changeMask>0
bitsToChange = bitsToChange + (changeMask AND 1)
changeMask = changeMask >> 1
loop
return bitsToChange
Good old-fashioned bit operations!
size_t countbits( unsigned int n )
{
size_t bits = 0;
while( n )
{
bits += n&1;
n >>= 1;
}
return bits;
}
countbits( a ^ b );
This could would work in C as well as C++. You could (in C++ only) make the countbits function a template.
Actually,humbly building on previous answer - this might work better for converting a to b:
the only difference with previous answer is that the bits already set in b dont need to be set again - so dont count them.
calculate (a XOR b) AND ~b
count the set bits
post corrected as per comment. Thanks!
abs(popcount(a) - popcount(b)) where popcount counts bits set in number (a lot of different variants exists)

easy and fast way to convert an int to binary?

What I am looking for is something like PHPs decbin function in C#. That function converts decimals to its representation as a string.
For example, when using decbin(21) it returns 10101 as result.
I found this function which basically does what I want, but maybe there is a better / faster way?
var result = Convert.ToString(number, 2);
– Almost the only use for the (otherwise useless) Convert class.
Most ways will be better and faster than the function that you found. It's not a very good example on how to do the conversion.
The built in method Convert.ToString(num, base) is an obvious choice, but you can easily write a replacement if you need it to work differently.
This is a simple method where you can specify the length of the binary number:
public static string ToBin(int value, int len) {
return (len > 1 ? ToBin(value >> 1, len - 1) : null) + "01"[value & 1];
}
It uses recursion, the first part (before the +) calls itself to create the binary representation of the number except for the last digit, and the second part takes care of the last digit.
Example:
Console.WriteLine(ToBin(42, 8));
Output:
00101010
int toBase = 2;
string binary = Convert.ToString(21, toBase); // "10101"
To have the binary value in (at least) a specified number of digits, padded with zeroes:
string bin = Convert.ToString(1234, 2).PadLeft(16, '0');
The Convert.ToString does the conversion to a binary string.
The PadLeft adds zeroes to fill it up to 16 digits.
This is my answer:
static bool[] Dec2Bin(int value)
{
if (value == 0) return new[] { false };
var n = (int)(Math.Log(value) / Math.Log(2));
var a = new bool[n + 1];
for (var i = n; i >= 0; i--)
{
n = (int)Math.Pow(2, i);
if (n > value) continue;
a[i] = true;
value -= n;
}
Array.Reverse(a);
return a;
}
Using Pow instead of modulo and divide so i think it's faster way.

Categories