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.
Related
I am fairly new to C programming, and I encountered bit masking. What is the general concept and function of bit masking?
Examples are much appreciated.
A mask defines which bits you want to keep, and which bits you want to clear.
Masking is the act of applying a mask to a value. This is accomplished by doing:
Bitwise ANDing in order to extract a subset of the bits in the value
Bitwise ORing in order to set a subset of the bits in the value
Bitwise XORing in order to toggle a subset of the bits in the value
Below is an example of extracting a subset of the bits in the value:
Mask: 00001111b
Value: 01010101b
Applying the mask to the value means that we want to clear the first (higher) 4 bits, and keep the last (lower) 4 bits. Thus we have extracted the lower 4 bits. The result is:
Mask: 00001111b
Value: 01010101b
Result: 00000101b
Masking is implemented using AND, so in C we get:
uint8_t stuff(...) {
uint8_t mask = 0x0f; // 00001111b
uint8_t value = 0x55; // 01010101b
return mask & value;
}
Here is a fairly common use-case: Extracting individual bytes from a larger word. We define the high-order bits in the word as the first byte. We use two operators for this, &, and >> (shift right). This is how we can extract the four bytes from a 32-bit integer:
void more_stuff(uint32_t value) { // Example value: 0x01020304
uint32_t byte1 = (value >> 24); // 0x01020304 >> 24 is 0x01 so
// no masking is necessary
uint32_t byte2 = (value >> 16) & 0xff; // 0x01020304 >> 16 is 0x0102 so
// we must mask to get 0x02
uint32_t byte3 = (value >> 8) & 0xff; // 0x01020304 >> 8 is 0x010203 so
// we must mask to get 0x03
uint32_t byte4 = value & 0xff; // here we only mask, no shifting
// is necessary
...
}
Notice that you could switch the order of the operators above, you could first do the mask, then the shift. The results are the same, but now you would have to use a different mask:
uint32_t byte3 = (value & 0xff00) >> 8;
Masking means to keep, change, or remove a desired part of information. Let’s see an image-masking operation; like this masking operation is removing anything that is not skin:
We are doing an AND operation in this example. There are also other masking operators—OR and XOR.
Bitmasking means imposing mask over bits. Here is a bitmasking with AND—
1 1 1 0 1 1 0 1 input
(&) 0 0 1 1 1 1 0 0 mask
------------------------------
0 0 1 0 1 1 0 0 output
So, only the middle four bits (as these bits are 1 in this mask) remain.
Let’s see this with XOR—
1 1 1 0 1 1 0 1 input
(^) 0 0 1 1 1 1 0 0 mask
------------------------------
1 1 0 1 0 0 0 1 output
Now, the middle four bits are flipped (1 became 0, 0 became 1).
So, using a bitmask, we can access individual bits (examples). Sometimes, this technique may also be used for improving performance. Take this for example-
bool isOdd(int i) {
return i%2;
}
This function tells if an integer is odd/even. We can achieve the same result with more efficiency using a bit-mask—
bool isOdd(int i) {
return i&1;
}
Short Explanation: If the least significant bit of a binary number is 1 then it is odd; for 0 it will be even. So, by doing AND with 1 we are removing all other bits except for the least significant bit, i.e.:
55 -> 0 0 1 1 0 1 1 1 input
(&) 1 -> 0 0 0 0 0 0 0 1 mask
---------------------------------------
1 <- 0 0 0 0 0 0 0 1 output
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
I am fairly new to C programming, and I encountered bit masking. What is the general concept and function of bit masking?
Examples are much appreciated.
A mask defines which bits you want to keep, and which bits you want to clear.
Masking is the act of applying a mask to a value. This is accomplished by doing:
Bitwise ANDing in order to extract a subset of the bits in the value
Bitwise ORing in order to set a subset of the bits in the value
Bitwise XORing in order to toggle a subset of the bits in the value
Below is an example of extracting a subset of the bits in the value:
Mask: 00001111b
Value: 01010101b
Applying the mask to the value means that we want to clear the first (higher) 4 bits, and keep the last (lower) 4 bits. Thus we have extracted the lower 4 bits. The result is:
Mask: 00001111b
Value: 01010101b
Result: 00000101b
Masking is implemented using AND, so in C we get:
uint8_t stuff(...) {
uint8_t mask = 0x0f; // 00001111b
uint8_t value = 0x55; // 01010101b
return mask & value;
}
Here is a fairly common use-case: Extracting individual bytes from a larger word. We define the high-order bits in the word as the first byte. We use two operators for this, &, and >> (shift right). This is how we can extract the four bytes from a 32-bit integer:
void more_stuff(uint32_t value) { // Example value: 0x01020304
uint32_t byte1 = (value >> 24); // 0x01020304 >> 24 is 0x01 so
// no masking is necessary
uint32_t byte2 = (value >> 16) & 0xff; // 0x01020304 >> 16 is 0x0102 so
// we must mask to get 0x02
uint32_t byte3 = (value >> 8) & 0xff; // 0x01020304 >> 8 is 0x010203 so
// we must mask to get 0x03
uint32_t byte4 = value & 0xff; // here we only mask, no shifting
// is necessary
...
}
Notice that you could switch the order of the operators above, you could first do the mask, then the shift. The results are the same, but now you would have to use a different mask:
uint32_t byte3 = (value & 0xff00) >> 8;
Masking means to keep, change, or remove a desired part of information. Let’s see an image-masking operation; like this masking operation is removing anything that is not skin:
We are doing an AND operation in this example. There are also other masking operators—OR and XOR.
Bitmasking means imposing mask over bits. Here is a bitmasking with AND—
1 1 1 0 1 1 0 1 input
(&) 0 0 1 1 1 1 0 0 mask
------------------------------
0 0 1 0 1 1 0 0 output
So, only the middle four bits (as these bits are 1 in this mask) remain.
Let’s see this with XOR—
1 1 1 0 1 1 0 1 input
(^) 0 0 1 1 1 1 0 0 mask
------------------------------
1 1 0 1 0 0 0 1 output
Now, the middle four bits are flipped (1 became 0, 0 became 1).
So, using a bitmask, we can access individual bits (examples). Sometimes, this technique may also be used for improving performance. Take this for example-
bool isOdd(int i) {
return i%2;
}
This function tells if an integer is odd/even. We can achieve the same result with more efficiency using a bit-mask—
bool isOdd(int i) {
return i&1;
}
Short Explanation: If the least significant bit of a binary number is 1 then it is odd; for 0 it will be even. So, by doing AND with 1 we are removing all other bits except for the least significant bit, i.e.:
55 -> 0 0 1 1 0 1 1 1 input
(&) 1 -> 0 0 0 0 0 0 0 1 mask
---------------------------------------
1 <- 0 0 0 0 0 0 0 1 output
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.
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;
}