Optimize bitflag check - c

How can I optimize the following code?
( (kbd_flags & KBD_FLAG_SHIFT) && !(kbd_flags & KBD_FLAG_CAPS))
|| (!(kbd_flags & KBD_FLAG_SHIFT) && (kbd_flags & KBD_FLAG_CAPS))
Basically, I want to check if either KBD_FLAG_SHIFT or KBD_FLAG_CAPS is set, but not both.

I would like to share my solution after doing some research. Zodoh's expression can be simplified to
kbd_flags & KBD_FLAG_SHIFT
? !(kbd_flags & KBD_FLAG_CAPS)
: kbd_flags & KBD_FLAG_CAPS
(Omitting unneeded parentheses and the true and false expressions)
Another interesting way I figured out is the following:
x = kbd_flags & (KBD_FLAG_SHIFT | KBD_FLAG_CAPS);
return x && (x & x - 1) == 0;
This works because of the way two's complement notation is designed. As an example, if kbd_flags is set to 001000, x - 1 will be 000111 and 001000 & 000111 is 000000. As a result, 000000 is equal to 0, thus returning true. The first x expression makes sure that the "no bit set" case is excluded.
It will also work with more than only two bit flags:
#define A 0x01
#define B 0x02
#define C 0x04
#define D 0x08
#define E 0x10
#define F 0x20
x = flags & (A | B | C | D | E | F);
return x && (x & x - 1) == 0;
Here, the expression x && (x & x - 1) == 0 will be true if and only if one of the flags A through F is set.
A quick test (f being the integer holding the flags to test for):
int f, x;
for (f = 0; f <= F + 1; f++) {
x = f & (A | B | C | D | E | F);
printf("0x%02x %d%d%d%d%d%d -> %d\n", f
, (f & A) == A, (f & B) == B, (f & C) == C
, (f & D) == D, (f & E) == E, (f & F) == F
, x && (x & x - 1) == 0);
}
This code will output the follwing:
0x00 000000 -> 0
0x01 100000 -> 1
0x02 010000 -> 1
0x03 110000 -> 0
0x04 001000 -> 1
0x05 101000 -> 0
0x06 011000 -> 0
0x07 111000 -> 0
0x08 000100 -> 1
0x09 100100 -> 0
0x0a 010100 -> 0
0x0b 110100 -> 0
0x0c 001100 -> 0
0x0d 101100 -> 0
0x0e 011100 -> 0
0x0f 111100 -> 0
0x10 000010 -> 1
0x11 100010 -> 0
0x12 010010 -> 0
0x13 110010 -> 0
0x14 001010 -> 0
0x15 101010 -> 0
0x16 011010 -> 0
0x17 111010 -> 0
0x18 000110 -> 0
0x19 100110 -> 0
0x1a 010110 -> 0
0x1b 110110 -> 0
0x1c 001110 -> 0
0x1d 101110 -> 0
0x1e 011110 -> 0
0x1f 111110 -> 0
0x20 000001 -> 1
0x21 100001 -> 0
As you can see, x && (x & x - 1) == 0 is true iff one bit is set.

You can use this
(kbd_flags & KBD_FLAG_SHIFT) ? ((kbd_flags & KBD_FLAG_CAPS)? false : true) : ((kbd_flags & KBD_FLAG_CAPS)? true : false)
Else is you know how to use the bits you can use the XOR operator ^.
A = 0000 0001
B = 0000 0000
A ^ B = 0000 0001
A = 0000 0000
B = 0000 0001
A ^ B = 0000 0001
A = 0000 0000
B = 0000 0000
A ^ B = 0000 0000
A = 0000 0001
B = 0000 0001
A ^ B = 0000 0000

To answer more clearly.
(kbd_flags & KBD_FLAG_SHIFT) ^ (kbd_flags & KBD_FLAG_CAPS)
This should work.

Related

What is if (c >> a & 1) does mean?

I'm trying to understand what is this condition mean.
Does it mean after shifting the value it will be equal to 1?
I mean does it mean --> if (c >> a is 1)
Note: c >> a & 1 same as (c >> a) & 1.
Bitwise AND operate on bits, so the possibilities are :
1101 & 0001 => 0001
0001 & 0001 => 0001
1010 & 0001 => 0000
0000 & 0001 => 0000
Now, on C, anything that's not a zero is treated as true, so the statement means "if after shifting the least significant bit is 1", or perhaps "if after shifting the value is odd" if you're dealing with odd-even operation.
It executes the following statement or block if bit a of value c is true.
a+1 a a-1 1 0
... --+---+---+---+-- ... -+---+---+
| z | y | x | | q | p |
... --+---+---+---+-- ... -+---+---+
... -+---+---+
>> a | z | y |
... -+---+---+
... -+---+---+
&& 1 | 0 | y |
... -+---+---+
>> has higher operator precedence than &.
So c >> a & 1 means "shift the value c by a bits to the right, then check if the lowest bit of the shifted value is set. To single out certain bit values like this is known as bit masking and 1 in this case is the mask.

Faster way for extracting and combining bits from UINT16 to UINT8

I'm searching for a faster way for my required special extract and combine operation as described below:
+-------+-------+-------+-------+-------+-------+-------+-------+
| BIT 7 | BIT 6 | BIT 5 | BIT 4 | BIT 3 | BIT 2 | BIT 1 | BIT 0 |
+-------+-------+-------+-------+-------+-------+-------+-------+
| D1 | D0 | C1 | C0 | B1 | B0 | A1 | A0 |
+-------+-------+-------+-------+-------+-------+-------+-------+
A = A0 OR A1
B = B0 OR B1
C = C0 OR C1
D = D0 OR D1
+-------+-------+-------+-------+-------+-------+-------+-------+
| BIT 7 | BIT 6 | BIT 5 | BIT 4 | BIT 3 | BIT 2 | BIT 1 | BIT 0 |
+-------+-------+-------+-------+-------+-------+-------+-------+
| | | | | D | C | B | A |
+-------+-------+-------+-------+-------+-------+-------+-------+
For sake of simplicity above is only an 8-bit example, the same applies for 16 bit values. It should be implemented as fast as possible on dsPIC33F microcontroller.
The easy way in C is:
PairFlags |= (ChannelFlags & 0x0003) ? 0x0001 : 0;
PairFlags |= (ChannelFlags & 0x000C) ? 0x0002 : 0;
PairFlags |= (ChannelFlags & 0x0030) ? 0x0004 : 0;
PairFlags |= (ChannelFlags & 0x00C0) ? 0x0008 : 0;
PairFlags |= (ChannelFlags & 0x0300) ? 0x0010 : 0;
PairFlags |= (ChannelFlags & 0x0C00) ? 0x0020 : 0;
PairFlags |= (ChannelFlags & 0x3000) ? 0x0040 : 0;
PairFlags |= (ChannelFlags & 0xC000) ? 0x0080 : 0;
This will produce approx. 40 instructions (with O3) which corresponds to 1µs in my case.
The amount of instruction cycles should be reduced if possible. Is there a faster way either in C or inline assembly?
The following should work for reducing a 16-bit value to 8 bits (with each bit of output formed by ORing a pair of bits of input):
// Set even bits to bits in pair ORed together, and odd bits to 0...
PairFlags = (ChannelFlags | (ChannelFlags >> 1)) & 0x5555; // '0h0g0f0e0d0c0b0a'
// Compress the '00' or '01' bit pairs down to single '0' or '1' bits...
PairFlags = (PairFlags ^ (PairFlags >> 1)) & 0x3333; // '00hg00fe00dc00ba'
PairFlags = (PairFlags ^ (PairFlags >> 2)) & 0x0F0F; // '0000hgfe0000dcba'
PairFlags = (PairFlags ^ (PairFlags >> 4)) & 0x00FF; // '00000000hgfedcba'
Note: The ^ can be replaced by | in the above for the same result.
Assuming I got everything right (not tested), this seems to generate good, branch-free code at least on gcc and clang for x86 (-O3):
uint8_t convert (uint8_t ChannelFlags)
{
return ( ((ChannelFlags & A1A0)!=0) << A_POS ) |
( ((ChannelFlags & B1B0)!=0) << B_POS ) |
( ((ChannelFlags & C1C0)!=0) << C_POS ) |
( ((ChannelFlags & D1D0)!=0) << D_POS ) ;
}
This masks out each individual bitset, then check against zero to end up with 1 or 0 in a temporary int. This value is shifted in position in the result, before everything is finally bitwise OR:ed together. Full code:
#include <stdint.h>
#define A1A0 (3u << 0)
#define B1B0 (3u << 2)
#define C1C0 (3u << 4)
#define D1D0 (3u << 6)
#define A_POS 0
#define B_POS 1
#define C_POS 2
#define D_POS 3
uint8_t convert (uint8_t ChannelFlags)
{
return ( ((ChannelFlags & A1A0)!=0) << A_POS ) |
( ((ChannelFlags & B1B0)!=0) << B_POS ) |
( ((ChannelFlags & C1C0)!=0) << C_POS ) |
( ((ChannelFlags & D1D0)!=0) << D_POS ) ;
}
clang disassembly x86 gives 18 instructions branch free:
convert: # #convert
test dil, 3
setne al
test dil, 12
setne cl
add cl, cl
or cl, al
test dil, 48
setne al
shl al, 2
or al, cl
mov ecx, edi
shr cl, 7
shr dil, 6
and dil, 1
or dil, cl
shl dil, 3
or al, dil
ret
Not sure if more efficient but instead of using a ternary if, why not use only bitwise operations ? And just offset it with the bitshift operator
PairFlags = ((ChannelFlags & (0b1 << 0)) | (ChannelFlags & (0b10 << 0))) << 0;
PairFlags = ((ChannelFlags & (0b1 << 2)) | (ChannelFlags & (0b10 << 2))) << 1;
PairFlags = ((ChannelFlags & (0b1 << 4)) | (ChannelFlags & (0b10 << 4))) << 2;
//...
Here is an idea.
Observe one thing here:
A = A0 OR A1
B = B0 OR B1
C = C0 OR C1
D = D0 OR D1
You have 4 or operations. You can perform all of them in 1 instruction:
PairFlags = (PairFlags | (PairFlags >> 1))
Now you bits are aligned like that:
[D1][D1 or D0][D0 or C1][C1 or C0][C0 or B1][B1 or B0][B0 or A1][A1 or A0]
So you just need to extract bits 0, 2, 4, 6 to get the result.
Bit 0. Is already OK.
Bit 1 should be set to bit 2.
Bit 2 should be set to bit 4.
Bit 3 should be set to bit 6.
Final code something like that:
PairFlags = (PairFlags | (PairFlags >> 1))
PairFlags = (PairFlags&1) | ((PairFlags&4)>>1) | ((PairFlags&16)>>2) | ((PairFlags&64)>>3)

swap hex binary with rule

please i need a how to do in linux for swap job.
my exemple :
9882 swaped to 016C
and
3030 swaped to 0303
like this
1001 1000 1000 0010 = 9882 : bin
0000 0001 0110 1100 = 016C : bin swap
bin before swap :
0 1 2 3 4 5 6 7 8 9 A B C D E F
1 0 0 1 1 0 0 0 1 0 0 0 0 0 1 0
bin after swap :
0 1 2 3 4 5 6 7 8 9 A B C D E F
0 0 0 0 0 0 0 1 0 1 1 0 1 1 0 0
with swap rule :
bin_SWAP[0] = bin[D];
bin_SWAP[1] = bin[5];
bin_SWAP[2] = bin[6];
bin_SWAP[3] = bin[7];
bin_SWAP[4] = bin[9];
bin_SWAP[5] = bin[1];
bin_SWAP[6] = bin[2];
bin_SWAP[7] = bin[3];
bin_SWAP[8] = bin[C];
bin_SWAP[9] = bin[4];
bin_SWAP[A] = bin[E];
bin_SWAP[B] = bin[F];
bin_SWAP[C] = bin[8];
bin_SWAP[D] = bin[0];
bin_SWAP[E] = bin[A];
bin_SWAP[F] = bin[B];
there is any program in linux can swap a file with more than 64 bytes
my exmple do with 2 bytes.
thanks in advance.
another exmple for more simplify
swap 4 bytes
B455CBD5
B455
1011 0100 0101 0101 : bin
0123 4567 89AB CDEF : position
1100 1011 0001 0101 : bin swap
CB15
CBD5
1100 1011 1101 0101 : bin
0123 4567 89AB CDEF : position
1011 1100 0111 1101 : bin swap
BC7D
than the result is
CB15BC7D

Bitwise & and I

Why is 1 & 4 = 0
whereas
1 | 4 evaluates to 5
Well.. because.
For &, the AND operator:
0001 = 1
0100 = 4
---- (AND)
0000 = 0
for |, the OR operator:
0001 = 1
0100 = 4
---- (OR)
0101 = 5
Bitwise & => If both bits are higher, then the output is higher else output is zero.
0 0 1
1 0 0
-----
0 0 0 => 0 // 1 & 1 = 1 , 1 & 0 = 0
Now try yourself Bitwise |. Any of the bit is higher, output is higher.
1 is 0b001, and 4 is 0b100, so, naturally, 1&4 is 0b000 and 1|4 is 0b101, which is 5.
Look at it in binary form.
1d(ecimal) = 001b(inary)
4d(ecimal) = 100b(inary)
thus
001b
100b & (both bits have to be 1 to yield 1)
--
000b = 0d
and
001b
100b | (only one on either side (or both) has to be 1 to yield 1)
--
101b = 5d

How to think of bit operations for simple operations?

for example:
unsigned int a; // value to merge in non-masked bits
unsigned int b; // value to merge in masked bits
unsigned int mask; // 1 where bits from b should be selected; 0 where from a.
unsigned int r; // result of (a & ~mask) | (b & mask) goes here
r = a ^ ((a ^ b) & mask);
merges bits from two values according to the mask.
[taken from here]
In this case, I can see that it works, but I am not sure what the logic is? And I am not sure I can create my own bit operations like this from scratch. How do I start thinking in bits?
Pencil and paper helps the best in cases like this. I usually write it down:
a = 10101110
b = 01100011
mask = 11110000
a ^ b = 10101110
01100011
--------
x => 11001101
x & mask = 11001101
11110000
--------
x => 11000000
a ^ x = 11000000
10101110
--------
x => 01101110
(final x is your r)
I don't know if this is the result you were after, but that's what it does. Writing it out usually helps when I don't understand a bitwise operation.
In this case, I can see that it works, but I am not sure what the logic is? And I am not sure I can create my own bit operations like this from scratch. How do I start thinking in bits?
People have answered your first question -- explaining the logic. I shall hopefully show you a terribly basic, long-winded but standard method of making any bit twiddling operations. (note, once you get used to working with bits you'll start thinking in & and | straight off without doing such nonsense).
Figure out what you'd like your operation to do.
Write out a FULL truth table.
Either read the sum-of-products direct from the table or make a Karnaugh map. The km will reduce the final eqution a lot.
???
Profit
Deriving for the example you gave. ie, where a mask selects bits from A or B. (0 is A, 1 is B)
This table is for 1 bit per input. I'm not doing more than one bit, as I don't want to waste my time :) ( why? 2^(2bits * 3inputs) = 64 cases :( 2^(3bits * 3inputs) = 512 cases :(()
But the good news is that in this case the operation is independant of the number of bits, so a 1 bit example is 100% fine. Infact it's recommended by me :)
| A | B | M || R |
============++====
| 0 | 0 | 0 || 0 |
| 0 | 0 | 1 || 0 |
| 0 | 1 | 0 || 0 |
| 0 | 1 | 1 || 1 |
| 1 | 0 | 0 || 1 |
| 1 | 0 | 1 || 0 |
| 1 | 1 | 0 || 1 |
| 1 | 1 | 1 || 1 |
Hopefully you can see how this truth table works.
how to get an expression from this? Two methods: KMaps and by-hand. Let's do it by-hand first, should we? :)
Looking at the points where R is true, we see:
| A | B | M || R |
============++====
| 0 | 1 | 1 || 1 |
| 1 | 0 | 0 || 1 |
| 1 | 1 | 0 || 1 |
| 1 | 1 | 1 || 1 |
From this we can dervive an expresion:
R = (~A & B & M) |
( A & ~B & ~M) |
( A & B & ~M) |
( A & B & M) |
Hopefully you can see how this works: just or together the full expressions seen in each case. By full I imply that you need to not-variables i nthere.
Let's try it in python:
a = 0xAE #10101110b
b = 0x64 #01100011b
m = 0xF0 #11110000b
r = (~a & b & m) | ( a & ~b & ~m) | ( a & b & ~m) | ( a & b & m)
print hex(r)
OUTPUT:
0x6E
These numbers are from Abel's example. The output is 0x6E, which is 01101110b.
So it worked! Hurrah. (ps, it's possible to derive an expression for ~r from the first table, should you wish to do so. Just take the cases where r is 0).
This expression you've made is a boolean "sum of products", aka Disjunctive Normal Form, although DNF is really the term used when using first-order predicate logic. This expression is also pretty unweidly. Making it smaller is a tedious thing to do on paper, and is the kind of thing you'll do 500,000 times at Uni' on a CS degree if you take the compiler or hardware courses. (Highly recommended :))
So let's do some boolean algebra magic on this (don't try and follow this, it's a waste of time):
(~a & b & m) | ( a & ~b & ~m) | ( a & b & ~m) | ( a & b & m)
|= ((~a & b & m) | ( a & ~b & ~m)) | ( a & b & ~m) | ( a & b & m)
take that first sub-clause that I made:
((~a & b & m) | ( a & ~b & ~m))
|= (~a | (a & ~b & ~m)) & (b | ( a & ~b & ~m)) & (m | ( a & ~b & ~m))
|= ((~a | a) & (a | ~b) &( a | ~m)) & (b | ( a & ~b & ~m)) & (m | ( a & ~b & ~m))
|= (T & (a | ~b) &( a | ~m)) & (b | ( a & ~b & ~m)) & (m | ( a & ~b & ~m))
|= ((a | ~b) & (a | ~m)) & (b | ( a & ~b & ~m)) & (m | ( a & ~b & ~m))
etc etc etc. This is the massively tedious bit incase you didn't guess. So just whack the expression in a website of your choice, which will tell you
r = (a & ~m) | (b & m)
Hurrah! Correct result. Note, it might even go so far as giving you an expression involving XORs, but who cares? Actually, some people do, as the expression with ands and ors is 4 operations (1 or, 2 and, 1 neg), whilst r = a ^ ((a ^ b) & mask) is 3 (2 xor, 1 and).
Now, how do you do it with kmaps? Well, first you need to know how to make them, I'll leave you to do that. :) Just google for it. There's software available, but I think it's best to do it by hand -- it's more fun and the programs don't allow you to cheat.
Cheat? Well, if you have lots of inputs, it's often best to reduce the table like so:
| A | B | M || R |
============++====
| X | X | 0 || A |
| X | X | 1 || B |
eg that 64 case table?
| A1| A0| B1| B0| M1| M0|| R1| R0|
========================++========
| X | X | X | X | 0 | 0 || A1| A0|
| X | X | X | X | 0 | 1 || A1| B0|
| X | X | X | X | 1 | 0 || B1| A0|
| X | X | X | X | 1 | 1 || B1| B0|
Boils down to 4 cases in this example :)
(Where X is "don't care".) Then put that table in your Kmap. Once again, an exercise for you to work out [ie, I've forgotten how to do this].
Hopefully you can now derive your own boolean madness, given a set of inputs and an expected set of outputs.
Have fun.
In order to create boolean expressions like that one, I think you'd have to learn some boolean algebra.
This looks good:
http://www.allaboutcircuits.com/vol_4/chpt_7/1.html
It even has a page on generating boolean expressions from truth tables.
It also has a section on Karnaugh Maps. To be honest, I've forgotten what those are, but they look like they could be useful for what you want to do.
http://www.allaboutcircuits.com/vol_4/chpt_8/1.html
a ^ x for some x gives the result of flipping those bits in a which are set in x.
a ^ b gives you a 1 where the bits in a and b differ, a 0 where they are the same.
Setting x to (a ^ b) & mask gives the result of flipping the bits in a which are different in a and b and are set in the mask. Thus a ^ ((a ^ b) & mask) gives the result of changing, where necessary, the values of the bits which are set in the mask from the value they take in a to the value they take in b.
The basis for most bitwise operations (&, |, ^, ~) is Boolean algebra. Think of performing Boolean algebra to multiple Boolean values in parallel and you've got the bitwise operators. The only operators this doesn't cover are the shift operators (<<, >>), which you can think of as shifting the bits or as multiplication by powers of two. x << 3 == x * pow(2,3) and x >> 4 == (int)(x * pow(2,-4)).
Thinking in bits in not that hard, you just need to convert, in your head, all the values into bits and work on them a bit at a time. That sounds hard but it does get easier over time. A good first step is to start thinking of them as hex digits (4 bits at a time).
For example, let's say a is 0x13, b is 0x22 and mask is 0x0f:
a : 0x13 : 0001 0011
b : 0x22 : 0010 0010
---------------------------------
a^b : 0x31 : 0011 0001
mask : 0x0f : 0000 1111
---------------------------------
(a^b)&mask : 0x01 : 0000 0001
a : 0x13 : 0001 0011
---------------------------------
a^((a^b)&mask) : 0x12 : 0001 0010
This particular example is a way to combine the top four bits of a with the bottom 4 bits of b (the mask decides which bits come from a and b.
As the site says, it's an optimization of (a & ~mask) | (b & mask):
a : 0x13 : 0001 0011
~mask : 0xf0 : 1111 0000
---------------------------------
a & ~mask : 0x10 : 0001 0000
b : 0x22 : 0010 0010
mask : 0x0f : 0000 1111
---------------------------------
b & mask : 0x20 : 0000 0010
a & ~mask : 0x10 : 0001 0000
b & mask : 0x20 : 0000 0010
---------------------------------
(a & ~mask) | : 0x12 : 0001 0010
(b & mask)
Aside: I wouldn't be overly concerned about not understanding something on that page you linked to. There's some serious "black magic" going on there. If you really want to understand bit fiddling, start with unoptimized ways of doing it.
First learn the logical (that is, 1-bit) operators well. Try to write down some rules, like
a && b = b && a
1 && a = a
1 || a = 1
0 && a = ... //you get the idea. Come up with as many as you can.
Include the "logical" xor operator:
1 ^^ b = !b
0 ^^ b = ...
Once you have a feel for these, move onto bitwise operators. Try some problems, look at some common tricks and techniques. With a bit of practice you'll feel much more confident.
Break the expression down into individual bits. Consider a single bit position in the expression (a ^ b) & mask. If the mask has zero at that bit position, (a ^ b) & mask will simply give you zero. Any bit xor'ed with zero will remain unchanged, so a ^ (a ^ b) & mask will simply return a's original value.
If the mask has a 1 at that bit position, (a ^ b) & mask will simply return the value of a ^ b. Now if we xor the value with a, we get a ^ (a ^ b) = (a ^ a) ^ b = b. This is a consequence of a ^ a = 0 -- any value xor'ed with itself will return zero. And then, as previously mentioned, zero xor'ed with any value will just give you the original value.
How to think in bits:
Read up on what others have done, and take note of their strategies. The Stanford site you link to is a pretty good resource -- there are often several techniques shown for a particular operation, allowing you to see the problem from different angles. You might have noticed that there are people who've submitted their own alternative solutions for a particular operation, which were inspired by the techniques applied to a different operation. You could take the same approach.
Also, it might help you to remember a handful of simple identities, which you can then string together for more useful operations. IMO listing out the results for each bit-combination is only useful for reverse-engineering someone else's work.
Maybe you dont need to think in bits - perhaps you can get your compiler to think in bits for you
and you can focus on the actual problem you're trying to solve instead. Using bit manipulation directly
in your code can produce some profoundly impenetrable (if impressive) code -- here's some nice macros
(from the windows ddk) that demonstrate this
// from ntifs.h
// These macros are used to test, set and clear flags respectivly
#define FlagOn(_F,_SF) ((_F) & (_SF))
#define BooleanFlagOn(F,SF) ((BOOLEAN)(((F) & (SF)) != 0))
#define SetFlag(_F,_SF) ((_F) |= (_SF))
#define ClearFlag(_F,_SF) ((_F) &= ~(_SF))
now if you want to set a flag in a value you can simply say SetFlag(x, y) much clearer I think. Moreover
if you focus on the problem you're trying to address with your bit fiddling the mechanics will become
second nature without you having to expend any effort. Look after the bits and the bytes will look after
themselves!

Resources