How to insert zeros every x bits - c

I represent a square of 1s and 0s with an integer type variable. Here's what it might look like:
1 1 1 0
0 1 0 0
0 0 0 0
0 0 0 0
The corresponding integer is coded from the bottom right corner to the top left, and the top left corner corresponds to 2^0. An integer representation of this grid is: 0000 0000 0010 0111 (2) = 39(10)
The grid is always a square with known width. In my code, I need to increment the width by 1 a lot of times, thus changing the map to:
1 1 1 0 0
0 1 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
Which is equivalent to inserting a 0 every x = width bits (width = 4 in the example). Overflows can't happen because the size of the integer is much larger than required.
In C, how can I insert a zero every x bits?
Edit1: since this operation will be happening a lot of times on numerous grids, loops are to be avoided.
Edit2: the reason I use this packing is because I do bitwise operations between grids to search for combinations.

Look at the problem in the way you would look as adding 0 to every forth position in decimal number. What you would do in decimal is:
1 513 650 -> 105 130 650
You can see, that your are just preserving the numbers less than 10^3 and multiplying the rest by 10. Than preserving the number less than 10^7 (not 10^6, because you already multiplied) and multypling the right side by 10....
It works same way for binary.
#include <iostream>
#include <cmath>
int power(int x, int n){
return n == 1 ? x : x*power(x,n-1);
}
int main(int argc, char const *argv[])
{
int n = 4;
int grid = 1024;
int grid_len = std::floor(std::log2(grid)) ; // what is the position of last 1, = how long i need to insert 0
for (int steps = 0; steps*n < grid_len; ++steps)
{
std::cout << steps << std::endl;
int preserve = grid % power(2,n*(steps+1) );
grid = (grid - preserve) * 2;
grid += preserve;
}
std::cout << grid << std::endl;
return 0;
}
The code prints 71, which in binary is 1000111, so it works on example you provided.

Related

How to extract bits from a number in C?

I need to extract specific part (no of bits) of a short data type in C.
Fox example, i have a binary of 45 as 101101 and i just want 2 bits in middle such as (10)
I started with C code 2 days ago so don't given a lot of functions.
How do i extract them ?
Please search for bit-wise operations for more general information, and bit masking for your specific question. I wouldn't recommend to jump to bits if you are new to programming though.
The solution will slightly change depending on whether your input will be fixed in length. If it won't be fixed, you need to arrange you mask accordingly. Or you can use a different method, this is probably simplest way.
In order to get specific bits that you want, you can use bitmasking.
E.g you have 101101 and you want those middle two bits, if you & this with 001100, only bits that are 1 on the mask will remain unchanged in the source, all the other bits will be set to 0. Effectively, you will have those bits that you are interested in.
If you don't know what & (bitwise and) is, it takes two operands, and returns 1 only if first AND second operands are 1, returns 0 otherwise.
input : 1 0 1 1 0 1
mask : 0 0 1 1 0 0
result : 0 0 1 1 0 0
As C syntax, we can do this like:
unsigned int input = 45;
unsigned int mask = 0b001100; // I don't know if this is standard notation. May not work with all compilers
// or
unsigned int mask = 12; // This is equivalent
unsigned int result = input & mask; // result contains ...001100
As yo can see, we filtered the bits we wanted. The next step depends on what you want to do with those bytes.
At this point, the result 001100 corresponds to 12. I assume this is not really useful. What you can do is, you can move those bits around. In order to get rid of 0s at the right, we can shit it 2 bits to the right. For this, we need to use >> operator.
0 0 1 1 0 0 >> 2 ≡ 0 0 0 0 1 1
result = result >> 2; // result contains ...011
From there, you can set a bool variable to store each of them being 1 or 0.
unsigned char flag1 = result & 0b01; // or just 1
unsigned char flag2 = result & 0b10; // or just 2
You could do this without shifting at all but this way it's more clear.
You need to mask the bits that you want to extract. If suppose you want to create mask having first 4 bits set. Then you can do that by using:
(1 << 4) - 1
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
void print_bin(short n)
{
unsigned long i = CHAR_BIT * sizeof(n);
while(i--)
putchar('0' + ((n >> i) & 1));
printf("\n");
}
int main()
{
short num = 45; /* Binary 101101 */
short mask = 4; /* 4 bits */
short start = 0; /* Start from leftmost bit
position 0 */
print_bin((num >> start) & ((1 << mask) - 1)); /* Prints 1101 */
mask = 2; /* 2 bits */
start = 1; /* start from bit indexed at position 1 */
print_bin((num >> start) & ((1 << mask) - 1)); /* Prints 10 */
return 0;
}
Output:
0000000000001101
0000000000000010

how to find specific instruction using bit field? (bit comparison)

I want to find type of instruction(16-bit).
For example Type 0 instruction, it always has its leftmost two bit is 0.
0 0 ? ? ? ? ? ? ? ? ? ? ? ? ? ? (16-bit bit field; ? is don't care)
I want to find this type 0 instruction using only leftmost two bit.
What should I do? (C language)
Ultimately, I wanna find that an instruction(such as 0012345678910111 or 0098765432123456) is type 0 instruction.
Sorry for my english T_T.
I want some code like below (in Java)
if (instruction.containsBit(type0) == true)
You use the & (bitwise AND) to mask out the relevant bits, then == to do the comparison:
uint16_t opcode = 0xf001;
if((opcode & 0xc000) == 0)
{
printf("opcode 0x%0x has topmost two bits cleared", opcode);
}
The 0xc000 constant, typically called "the mask" in code like this, is 1100 0000 0000 0000 in binary, so when applied with the bitwise AND, it will result in a number having 1s where both arguments have 1s. Comparing the result to 0 makes sure the opcode does not have any 1s in locations where the mask has 1s.
The operator & in C can perform an simple AND operation. See also here.
Then you just need the bitmask of the bits you want to check on the right-side of this operator.
#include <stdio.h>
int main (int argc, char **argv){
unsigned short a = 0x7FFF;
unsigned short b = 0x80FF;
if( a & 0x8000 ) printf("a Highest bit set\n");
if( a & 0x4000 ) printf("a Second highest bit set\n");
if( b & 0x8000 ) printf("b Highest bit set\n");
if( b & 0x4000 ) printf("b Second highest bit set\n");
return 0;
}
#define true ((uint8_t)1)
#define false ((uint8_t)0)
uint8_t IsThisInstructionType0(uint16_t instruction)
{
uint16_t andMask = 0x8000;
if(((instruction & andMAsk) >> 15) == 0)
{
andMask >>= 1;
if( ( ((instruction & andMAsk) << 1) >> 15 ) == 0)
return true;
}
else return false;
}
Something like this:
int GetInstructionClass (uint16_t ins)
{
return (ins>>14)&3;
}
This expression: (ins>>14)&3 works like this:
First, ins has this format:
C C X X X X X X X X X X X X X X
Where C are the bits that form the instruction class. X means "don't care for now".
The first operation, >>14 shifts the number to the right so it ends like this:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 C C
Note that as we are using an uint16_t, the shift operation should enter 0's from the left, but as the function result is int, and int is signed, I'm not sure if the type promotion happens before of after the shifting is performed. I'd say that the type promotion happens after the evaluation of the whole expression.
Anyway, and just to be sure that no unwanted bits will be returned, we will mask the result of the shifting so that only bits 0 and 1 are preserved. The mask is:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 which is 3.
So the final result will be a number with bits 0 and 1 being the same as bits 14 and 15 of the original ins argument, giving 0, 1, 2 or 3 (I repeat: I'm assuming that the whole expression is being treated as a 16 bit number). This works with MinGW, Visual C++ and GCC in a 32-bit environment.

Bitwise operation to compare a length subset of two bit streams [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
The "length" least significant bits of one address shall be compared with the "length" least significant bits of another address.
Can some one help me in getting the best optimal solution for the same?
Example:
address1 = 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 1 0 0 1
address2 = 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 1 1 0 0 1
If the comparison bits are 00100 then the above two addresses are same.
Apparently, you want to compare N least-significant bits. In that case your N is not a mask. "Mask" is an established term with very specific meaning. Your N is not a mask. It is just number of bits you have to compare.
To achieve that, you can start with actually generating a real mask from your N. This
uintptr_t mask = 1;
mask = (mask << N) - 1;
will create a mask that has 1s in N least-significant binary positions. (I don't know what type you use to store your addresses. That's the type you should use in place of uintptr_t.)
Then you can use that mask to compare your addresses
(address1 & mask) == (address2 & mask)
or
((address1 ^ address2) & mask) == 0
Alternatively, you can solve the same problem without using any masks at all. If your addresses have M bits total, then the comparison can be expressed as
(address1 << (M - N)) == (address2 << (M - N))
As #AndreyT wrote, you really are not describing a mask.
Trying to guess what you really do mean, here's my best attempt:
(assuming your int-size is 32-bits. You can convert to sizeof() or use 64 as appropriate)
(untested, but reasonably well commented, so you can test and fix it yourself)
void Compare(int addrA, int addrB, int nBits)
{
// This is all 1s in binary.
unsigned int mask = 0xFFFFFFFF;
mask = mask >> (32-nBits);
// Example: if nBits = 4
// then 32-4 = 28 and
// Mask == [1111] >> 28 == 28-zeros... followed by 4 Ones
if ((addrA & mask) == (addrB & mask))
{
printf("Same\n");
} else
{
printf("Not the same\n");
}
}
Sample Call
int main(void)
{
int address1 = 0x2A09; // 00000000 0010 1010 0000 1001
int address2 = 0x2A19; // 00000000 0010 1010 0001 1001
Compare(address1, address2, 4);
}
to turn the number 4 (or 00100) into the mask you want, you need
#define MASK(n) ((1 << (n)) - 1)
Also, if you are going to quote a binary representation of an integer, in C use 0b100, then we know you mean 4. 00100 is an octal constant.

Changing a value inside an array of bits

I have a "bitmap" lets say, 64 wide. Meaning 8 bits per Byte. 0000 0000 and let's say I want to activate the second bit, 0100 0000.
I tried making an array of unsigned char and using memcpy.
memcpy(bitmap[2], 1, sizeof(1));
I even tried declaring 1 in a unsigned char variable.
unsigned char bit = 1;
memcpy(bitmap[2], bit, sizeof(bit));
I know that strcpy wont solve anything in this case and memcpy isn't solving it either apparently, there is a proper way to do this for sure. I'm no C expert as you can see..
Maybe I shouldn't be trying to change the value inside the array like this?
let's assume that your bitmap looks like that
unsigned char bitmap[8] = {0};
and you want to activate the second bit (from the left) of the first byte in your bitmap array (bitmap[0]):
bitmap[0] = 1U<<6;
the bitmap[0] binary presentation will be 0100 0000
EDIT
bitmap[i] is 8 bits size.
bitmap[0] = 1<<6; // means 1 shifted to the left with 6 steps
1<<0
0 0 0 0 0 0 0 1
1<<1
0 0 0 0 0 0 1 0
1<<2
0 0 0 0 0 1 0 0
1<<3
0 0 0 0 1 0 0 0
......
1<<6
0 1 0 0 0 0 0 0

Understanding Bitwise Operations in This Function

For the sake of simplicity, let's just assume the integer I am passing to this function is 9 which is 1001 in binary.
It has been my goal for a while now to write my own integer to binary function in C. The way I used to figure out binary values for number in shorthand was as followed (using 9 as mentioned above):
9 / 2 = 4.5 (remainder) = 1
4 / 2 = 2 (no remainder) = 0
2 / 2 = 1 (no remainder) = 0
1 / 1 = 1 (remainder) = 1
So if you reverse the 1 0 0 1 we get you will have the binary value of 9 which is still 1 0 0 1.
But then after looking over this site I found that the binary value of an integer can be found with some "simple" bitwise arithmetic. I found a function on another post on this site and adapted it into a function of my own:
char *itob(int integer)
{
char *bin = 0X00, *tmp;
int bff = 0;
while(integer)
{
if(!(tmp = realloc(bin, bff + 1)))
{
free(bin);
printf("\nError! Memory allocation failed while building binary string.");
return 0x00;
}
bin = tmp;
if(integer & 1) bin[bff++] = '1';
else bin[bff++] = '0';
integer >>= 1;
}
bin[bff+1] = 0x00;
return bin;
}
Here is how I understand what is going on as well as my questions (that appear as comments)
1001 & 1 = 1 so put a 1 into the buffer //what is & doing that makes it equate to 1? Is it because the first digit in that sequence is a 1?
shift the bits in 1001 to the right one time
0010 & 1 != 1 so move a 0 into the buffer //same question as before is & just looking at the 0 because it is the first digit in the sequence?
shift the bits in 0010 to the right one time
0100 & 1 != 1 so move a 0 into the buffer //same question as before
shift the bits in 0100 to the right one time
1000 & 1 = 1 so put a 1 into the buffer //same question as before (at this point I'm thinking my theory is correct but I'm still not entirely sure)
shift the bits in 1000 to the right one time
loop ends
So as mentioned in my comments this is what I believe is going on in my program but I'm not 100% sure. Also I'm not sure if this is the best way to be even converting decimal to binary. (I'm already aware that if integer were for whatever reason to be a 0 I would eventually be trying to dereference a NULL pointer when trying to free the memory allocated by itob() along with a few other hiccups) But besides the questions that I already asked earlier is there a better method or more appropriate way to do this conversion?
No, the sequence of tests and shifts is
1001 & 1 => 1 then shift right
100 & 1 => 0 "
10 & 1 => 0 "
1 & 1 => 1 "
The resulting integer 0 makes the loop terminate. So what this does is test each bit starting with the least significant bit and append a 0 or 1 in the buffer. That I'd say is backwards because when printed as a string the bit sequence is reversed from the one used most often, where the least significant bit is the rightmost one.
thats seems correct reasoning
the only things is the function above gives the binary results back in reverse this is possibly not wanted...
you will not spot this with number 9 (1001) as its binary representation is the same both ways, but you will with the number 4 (0100)
Modelled after the one in my link. Untested, but should be allright.
char * bit2str(unsigned int num )
{
unsigned int bit,pos;
char *dst;
dst = malloc(1+CHAR_BIT*sizeof bit) ;
if (!dst) return NULL;
for(pos=0,bit = 1u << (CHAR_BIT*sizeof bit -1); bit; bit >>= 1 ) {
dst[pos++] = num & bit ? '1' : '0' ;
}
dst[pos] = 0;
return dst;
}

Resources