I'm trying to find a way to handle several bitfield cases that include optional, required, and not allowed positions.
yy?nnn?y
11000001
?yyy?nnn
01110000
nn?yyy?n
00011100
?nnn?yyy
00000111
In these four cases, the ? indicates that the bit can be either 1 or 0 while y indicates a 1 is required and n indicates that a 0 is required. The bits to the left/right of the required bits can be anything and the remaining bits must be 0. Is there a masking method I can use to test if an input bit set satisfies one of these cases?
Absolutely, but of course it depends on how you represent the "templates".
For example, say you represent them as a pair (z, o) where z has a 1 for every bit that is allowed to be 0 and o has a 1 for every bit that is allowed to be 1 (as in the paper I linked to in the comments). Then to test x against it you could do:
if ((x | z) == -1 && (x & o) == x)
passes test
You could also represent the templates as a pair (mask, bits), where mask is a mask of all bits that have to match (ie 0 means ?, 1 means a fixed bit) and bits is the values of the fixed bits. Then you could test x like:
if ((x & mask) == bits)
passes test
That's in general. If your problem has a special form, as it does in your question, you could use specialized tests.
Try something like this (using C/C++ notation):
(input & mask) == mask && (input & ~(mask | mask<<1 | mask>>1)) == 0
Related
The problem is to tell if two 8-bit chars are gray codes(differ only in 1 bit) in C++?
I found an elegant C++ solution:
bool isGray(char a, char b) {
int m = a ^ b;
return m != 0 && (m & (m - 1) & 0xff) == 0;
}
I was confused that what does the "& 0xff" do?
& 0xff extracts the 8 lowest bits from the resulting value, ignoring any higher ones.
It's wrong. The mistaken idea is that char is 8 bit.
It's also pointless. The presumed problem is that m can have more bits than char (true) so that "unnecessary" bits are masked off.
But m is sign-extended. That means the sign bit is copied to the higher bits. Now, when we're comparing x==0 we're checking whether all bits are zero, and with x & 0xff we're comparing if the lower 8 bits are zero. If the 8th bit of x is copied to all higher positions (by sign extension), then the two conditions are the same regardless of whether the copied bit was 0 or 1.
i am trying to do some exercises, but i'm stuck at this point, where i can't understand what's happening and can't find anything related to this particular matter (Found other things about logical operators, but still not enough)
EDIT: Why the downvote, i was pretty explicit. There is no information regarding the type of X, but i assume is INT, the size is not described either, i thought i would discover that by doing the exercise.
a) At least one bit of x is '1';
b) At least one bit of x is '0';
c) At least one bit at the Least Significant Byte of x , is '1';
d) At least one bit at the Least Significant Byte of x , is '0';
I have the solutions, but would be great to understand them
a) !!x // What happens here? The '!' Usually is NOT in c
b) !!~x // Again, the '!' appears... The bitwise operand NOT is '~' and it makes the int one's complement, no further realization made unfortunately
c) !!(x & 0xFF) // I've read that this is a bit mask, i think they take in consideration 4 bytes in X, and this applies a mask at the least significant byte?
d) !!(~x & 0xFF) // Well, at this point i'm lost ...
I would love not having to skip classes at college, but i work full time in order to pay the fees :( .
You can add brackets around the separate operations and apply them in order. e.g.
!(!(~x))
i.e. !! is 2 NOT's
What happens to some value if you perform one NOT is:
If x == 0 then !x == 1, otherwise !x == 0
So, if you would perform another NOT, you invert the truth-value again. i.e.
If x == 0 then !!x == 0, otherwise !!x == 1
You could see it as getting your value between 0 and 1 in which 0 means: "no bit of x is '1'", and 1 means: "at least one bit of x is '1'".
Also, x & 0xFF takes the least significant byte of your variable. More thoroughly explained here:
What does least significant byte mean?
Assuming x is some unsigned int/short/long/... and you want conditions (if, while...):
a) You´ll have to know that just a value/variable as condition (without a==b or something)
is false if it is 0 and true if it is not 0. So, if x is not 0 (true), one ! will switch it to 0 and the other ! to something not-0-like again (not necessarily the old value, only not 0). If x was 0, the ! will finally result in 0 again (first not 0, then again 0).
The whole value of x is not 0 if at least 1 bit is 1...
What you´re doing is to transform either 0 to 0 or a value with 1-bits to some value with 1-bits. Not wrong, but... You can just write if(x) instead of if(!!x)
b) ~ switches every 0-bit to 1 and every 1 to 0. Now you can search again a 1 because you want a 0 in the original value. The same !!-thing again...
c and d:
&0xFF sets all bits except for the lowest 8 ones (lowest byte) to 0.
The result of A&B is a value where each bit is only 1 if the bits of A an B at the same position are both 1. 0xff (decimal 255) is the number which has exactly the lowest 8 bits set to 1...
I'm not familiar with bitwise operations. I have this sequence:
1 0 0 0 0 : 16
---------------
0 1 1 1 1 : 15
---------------
0 1 1 1 0 : 14
---------------
.
.
.
---------------
0 0 0 1 1 : 3
---------------
0 0 0 1 0 : 2
---------------
0 0 0 0 1 : 1
---------------
I want to check first if there is more than one "1". If that's the case, I want to remove the one that has the bigger decimal value, and to finish, getting the bigger remaining. For example 15, there is four "1", I remove the bigger one, the "1" at "8", I got "0 0 1 1 1 : 7", where the bigger "1" is at "4". How can I do this?
Here's the code that does what you want:
unsigned chk_bits(unsigned int x) {
unsigned i;
if (x != 0 && (x & (x-1)) != 0) {
/* More than one '1' bit */
for (i = ~(~0U >> 1); (x & i) == 0; i >>= 1)
; /* Intentionally left blank */
return x & ~i;
}
return x;
}
Note that I assume you're dealing with unsigned numbers. This is usually safer, because right shifting is implementation defined on signed integers, because of sign extension.
The if statement checks if there's more than one bit set in x. x & (x-1) is a known way to get a number that is the same as x with the first '1' least significant bit turned off (for example, if x is 101100100, then x & (x-1) is 101100000. Thus, the if says:
If x is not zero, and if turning off the first bit set to 1 (from LSB to MSB) results in something that is not 0,
then...
Which is equivalent to saying that there's m ore than 1 bit set in x.
Then, we loop through every bit in x, stopping in the first most significant bit that is set. i is initialized to 1000000000000000000000000000, and the loop keeps right shifting it until x & i evaluates to something that is not zero, at which point we found the first most significant bit that is 1. At that point, taking i's complement will yield the mask to turn off this bit in x, since ~i is a number with every bit set to 1 except the only bit that was a 1 (which corresponds to the highest order bit in x). Thus, ANDing this with x gives you what you want.
The code is portable: it does not assume any particular representation, nor does it rely on the fact that unsigned is 32 or 64 bits.
UPDATE: I'm adding a more detailed explanation after reading your comment.
1st step - understanding what x & (x-1) does:
We have to consider two possibilities here:
x ends with a 1 (.......0011001)
x ends with a 0 (.......0011000)
In the first case, it is easy to see that x-1 is just x with the rightmost bit set to 0. For example, 0011001 - 1 = 0011000, so, effectively, x & (x-1) will just be x-1.
In the second case, it might be slightly harder to understand, but if the rightmost bit of x is a 0, then x-1 will be x with every 0 bit switched to a 1 bit, starting on the least significant bits, until a 1 is found, which is turned into a 0.
Let me give you an example, because this can be tricky for someone new to this:
1101011000 - 1 = 11101010111
Why is that? Because the previous number of a binary number ending with a 0 is a binary number filled with one or more 1 bits in the rightmost positions. When we increment it, like 10101111101111 + 1, we have to increment the next "free" position, i.e., the next 0 position, to turn it into a 1, and then all of the 1-bits to the right of that position are turned into 0. This is the way ANY base-n counting works, the only difference is that for base-2 you only have 0's and 1's.
Think about how base-10 counting works. When we run out of digits, the value wraps around and we add a new digit on the left side. What comes after 999? Well, the counting resets again, with a new digit on the left, and the 9's wrap around to 0, and the result is 1000. The same thing happens with binary arithmetic.
Think about the process of counting in binary; we just have 2 bits, 0 and 1:
0 (decimal 0)
1 (decimal 1 - now, we ran out of bits. For the next number, this 1 will be turned into a 0, and we need to add a new bit to the left)
10 (decimal 2)
11 (decimal 3 - the process is going to repeat again - we ran out of bits, so now those 2 bits will be turned into 0 and a new bit to the left must be added)
100 (decimal 4)
101 (decimal 5)
110 (the same process repeats again)
111
...
See how the pattern is exactly as I described?
Remember we are considering the 2nd case, where x ends with a 0. While comparing x-1 with x, rightmost 0's on x are now 1's in x-1, and the rightmost 1 in x is now 0 in x-1. Thus, the only part of x that remains the same is that on the left of the 1 that was turned into a 0.
So, x & (x-1) will be the same as x until the position where the first rightmost 1 bit was. So now we can see that in both cases, x & (x-1) will in fact delete the rightmost 1 bit of x.
2nd step: What exactly is ~0U >> 1?
The letter U stands for unsigned. In C, integer constants are of type int unless you specify it. Appending a U to an integer constant makes it unsigned. I used this because, as I mentioned earlier, it is implementation defined whether right shifting makes sign extension. The unary operator ~ is the complement operator, it grabs a number, and takes its complement: every 0 bit is turned into 1 and every 1 bit is turned into 0. So, ~0 is a number filled with 1's: 11111111111.... Then I shift it right one position, so now we have: 01111111...., and the expression for this is ~0U >> 1. Finally, I take the complement of that, to get 100000...., which in code is ~(~0U >> 1). This is just a portable way to get a number with the leftmost bit set to 1 and every other set to 0.
You can give a look at K&R chapter 2, more specifically, section 2.9. Starting on page 48, bitwise operators are presented. Exercise 2-9 challenges the reader to explain why x & (x-1) works. In case you don't know, K&R is a book describing the C programming language written by Kernighan and Ritchie, the creators of C. The book title is "The C Programming Language", I recommend you to get a copy of the second edition. Every good C programmer learned C from this book.
I want to check first if there is more than one "1".
If a number has a single 1 in its binary representation then it is a number that can be represented in the form 2x. For example,
4 00000100 2^2
32 00010000 2^5
So to check for single one, you can just check for this property.
If log2 (x) is a whole number then it has single 1 in it's binary representation.
You can calculate log2 (x)
log2 (x) = logy (x) / logy (2)
where y can be anything, which for standard log functions is either 10 or e.
Here is a solution
double logBase2 = log(num)/log(2);
if (logBase2 != (int)logBase2) {
int i = 7;
for (;i >0 ; i--) {
if (num & (1 << i)) {
num &= ~(1 << i);
break;
}
}
}
How would i go about accessing the individual bits inside a c++ type, char or any c++ other type for example.
If you want access bit N:
Get: (INPUT >> N) & 1;
Set: INPUT |= 1 << N;
Unset: INPUT &= ~(1 << N);
Toggle: INPUT ^= 1 << N;
You would use the binary operators | (or), & (and) and ^ (xor) to set them. To set the third bit of variable a, you would type, for instance:
a = a | 0x4
// c++ 14
a = a | 0b0100
Note that 4’s binary representation is 0100
That is very easy
Lets say you need to access individual bits of an integer
Create a mask like this
int mask =1;
now, anding your numberwith this mask gives the value set at the zeroth bit
in order to access the bit set at ith position (indexes start from zero) , just and with (mask<
If you want to look at the nth bit in a number you can use: number&(1<<n).
Essentially the the (1<<n) which is basically 2^n(because you shift the 1 bit in ...0001 n times, each left shift means multiply by 2) creates a number which happens to be 0 everywhere but 1 at the nth position(this is how math works).
You then & that with number. This returns a number which is either 0 everywhere or a number that has a 1 somewhere(essentially an integer which is either 0 or not).
Example:
2nd bit in in 4, 4&(1<<2)
0100
& 0010
____
0000 = 0
Therefore the 2nd bit in 4 is a 0
It will also work with chars because they are also numbers in C,C++
This question already has answers here:
How do I set, clear, and toggle a single bit?
(27 answers)
Closed 8 years ago.
We have an integer number
int x = 50;
in binary, it's
00110010
How can I change the fourth (4th) bit programatically?
You can set the fourth bit of a number by OR-ing it with a value that is zero everywhere except in the fourth bit. This could be done as
x |= (1u << 3);
Similarly, you can clear the fourth bit by AND-ing it with a value that is one everywhere except in the fourth bit. For example:
x &= ~(1u << 3);
Finally, you can toggle the fourth bit by XOR-ing it with a value that is zero everywhere except in the fourth bit:
x ^= (1u << 3);
To see why this works, we need to look at two things:
What is the behavior of the << operator in this context?
What is the behavior of the AND, OR, and XOR operators here?
In all three of the above code snippets, we used the << operator to generate a value. The << operator is the bitwise shift-left operator, which takes a value and then shifts all of its bits some number of steps to the left. In your case, I used
1u << 3
to take the value 1 (which has binary representation 1) and to then shift all its bits over three spots, filling in the missing values with 0. This creates the binary value 1000, which has a bit set in the fourth bit.
Now, why does
x |= (1u << 3);
set the fourth bit of the number? This has to do with how the OR operator works. The |= operator is like += or *= except for bitwise OR - it's equivalent to
x = x | (1u << 3);
So why does OR-ing x with the binary value 1000 set its fourth bit? This has to do with the way that OR is defined:
0 | 0 == 0
0 | 1 == 1
1 | 0 == 1
1 | 1 == 1
More importantly, though, we can rewrite this more compactly as
x | 0 == x
x | 1 == 1
This is an extremely important fact, because it means that OR-ing any bit with zero doesn't change the bit's value, while OR-ing any bit with 1 always sets that bit to one. This means that when we write
x |= (1u << 3);
since (1u << 3) is a value that is zero everywhere except in the fourth bit, the bitwise OR leaves all the bits of x unchanged except for the fourth bit, which is then set to one. More generally, OR-ing a number with a value that is a series of zeros and ones will preserve all the values where the bits are zero and set all of the values where the bits are one.
Now, let's look at
x &= ~(1u << 3);
This uses the bitwise complement operator ~, which takes a number and flips all of its bits. If we assume that integers are two bytes (just for simplicity), this means that the actual encoding of (1u << 3) is
0000000000001000
When we take the complement of this, we get the number
1111111111110111
Now, let's see what happens when we bitwise AND two values together. The AND operator has this interesting truth table:
0 & 0 == 0
0 & 1 == 0
1 & 0 == 0
1 & 1 == 1
Or, more compactly:
x & 0 == 0
x & 1 == x
Notice that this means that if we AND two numbers together, the resulting value will be such that all of the bits AND-ed with zero are set to zero, while all other bits are preserved. This means that if we AND with
~(1u << 3)
we are AND-ing with
1111111111110111
So by our above table, this means "keep all of the bits, except for the fourth bit, as-is, and then change the fourth bit to be zero."
More generally, if you want to clear a set of bits, create a number that is one everywhere you want to keep the bits unchanged and zero where you want to clear the bits.
Finally, let's see why
x ^= (1u << 3)
Flips the fourth bit of the number. This is because the binary XOR operator has this truth table:
0 ^ 0 == 0
0 ^ 1 == 1
1 ^ 0 == 1
1 ^ 1 == 0
Notice that
x ^ 0 == 0
x ^ 1 == ~x
Where ~x is the opposite of x; it's 0 for 1 and 1 for 0. This means that if we XOR x with the value (1u << 3), we're XOR-ing it with
0000000000001000
So this means "keep all the bits but the fourth bit set as is, but flip the fourth bit." More generally, if you want to flip some number of bits, XOR the value with a number that has zero where you want to keep the bits intact and one where you want to flip this bits.
Hope this helps!
You can always use std::bitset which makes modifying bits easy.
Or you can use bit manipulations (assuming you mean 4th bit counting at one. Don't subtract 1 if you mean counting from 0). Note that I use 1U just to guarantee that the whole operation happens on unsigned numbers:
To set: x |= (1U << (4 - 1));
To clear: x &= ~(1U << (4 - 1));
To toggle: x ^= (1U << (4 - 1));
To set the fourth bit, OR with 00001000 (binary).
To clear the fourth bit, AND with 11110111 (binary).
To toggle the fourth bit, XOR with 00001000 (binary).
Examples:
00110010 OR 00001000 = 00111010
00110010 AND 11110111 = 00110010
00110010 XOR 00001000 = 00111010
Simple, since you have, or whatever value you have,
int x = 50;
To set 4th bit (from right) programatically,
int y = x | 0x00000008;
Because, 0x prefixed before a number means it's hexadecimal form.
So, 0x0 = 0000 in binary, and 0x8=1000 in binary form.
That explains the answer.
Try one of these functions in C language to change n bit
char bitfield;
// start at 0th position
void chang_n_bit(int n, int value)
{
bitfield = (bitfield | (1 << n)) & (~( (1 << n) ^ (value << n) ));
}
void chang_n_bit(int n, int value)
{
bitfield = (bitfield | (1 << n)) & ((value << n) | ((~0) ^ (1 << n)));
}
void chang_n_bit(int n, int value)
{
if(value)
bitfield |= 1 << n;
else
bitfield &= ~0 ^ (1 << n);
}
char print_n_bit(int n)
{
return (bitfield & (1 << n)) ? 1 : 0;
}
You can use binary AND and OR to toggle the fourth bit.
To set the fourth bit on x, you would use x |= 1<<3;, 1<<3 being a left shift of 0b0001 by three bits producing 0b1000.
To clear the fourth bit on x, you would use x &= ~(1<<3);, a binary AND between 0b00110010 (x) and (effectively) 0b11110111, masking out every bit in x that is not in position four, thus clearing it.