Algorithm to generate bit mask - c

I was facing this unique problem of generating a bit-mask based on the input parameter. For example,
if param = 2, then the mask will be 0x3 (11b)
if param = 5, then the mask will be 0x1F (1 1111b)
This I implemented using a for-loop in C, something like
int nMask = 0;
for (int i = 0; i < param; i ++) {
nMask |= (1 << i);
}
I would like to know if there is a better algorithm ~~~

One thing to notice about bitmasks like that is that they are always one less than a power of two.
The expression 1 << n is the easiest way to get the n-th power of two.
You don't want Zero to provide a bitmask of 00000001, you want it to provide zero. So you need to subtract one.
mask = (1 << param) - 1;
Edit:
If you want a special case for param > 32:
int sizeInBits = sizeof(mask) * BITS_PER_BYTE; // BITS_PER_BYTE = 8;
mask = (param >= sizeInBits ? -1 : (1 << param) - 1);
This method should work for 16, 32, or 64 bit integers, but you may have to explicitly type the '1'.

Efficient, Branch-Free, Portable and Generic (but Ugly) Implementation
C:
#include <limits.h> /* CHAR_BIT */
#define BIT_MASK(__TYPE__, __ONE_COUNT__) \
((__TYPE__) (-((__ONE_COUNT__) != 0))) \
& (((__TYPE__) -1) >> ((sizeof(__TYPE__) * CHAR_BIT) - (__ONE_COUNT__)))
C++:
#include <climits>
template <typename R>
static constexpr R bitmask(unsigned int const onecount)
{
// return (onecount != 0)
// ? (static_cast<R>(-1) >> ((sizeof(R) * CHAR_BIT) - onecount))
// : 0;
return static_cast<R>(-(onecount != 0))
& (static_cast<R>(-1) >> ((sizeof(R) * CHAR_BIT) - onecount));
}
Usage (Producing Compile Time Constants)
BIT_MASK(unsigned int, 4) /* = 0x0000000f */
BIT_MASK(uint64_t, 26) /* = 0x0000000003ffffffULL */
Example
#include <stdio.h>
int main()
{
unsigned int param;
for (param = 0; param <= 32; ++param)
{
printf("%u => 0x%08x\n", param, BIT_MASK(unsigned int, param));
}
return 0;
}
Output
0 => 0x00000000
1 => 0x00000001
2 => 0x00000003
3 => 0x00000007
4 => 0x0000000f
5 => 0x0000001f
6 => 0x0000003f
7 => 0x0000007f
8 => 0x000000ff
9 => 0x000001ff
10 => 0x000003ff
11 => 0x000007ff
12 => 0x00000fff
13 => 0x00001fff
14 => 0x00003fff
15 => 0x00007fff
16 => 0x0000ffff
17 => 0x0001ffff
18 => 0x0003ffff
19 => 0x0007ffff
20 => 0x000fffff
21 => 0x001fffff
22 => 0x003fffff
23 => 0x007fffff
24 => 0x00ffffff
25 => 0x01ffffff
26 => 0x03ffffff
27 => 0x07ffffff
28 => 0x0fffffff
29 => 0x1fffffff
30 => 0x3fffffff
31 => 0x7fffffff
32 => 0xffffffff
Explanation
First of all, as already discussed in other answers, >> is used instead of << in order to prevent the problem when the shift count is equal to the number of bits of the storage type of the value. (Thanks Julien's answer above for the idea)
For the ease of discussion, let's "instantiate" the macro with unsigned int as __TYPE__ and see what happens (assuming 32-bit for the moment):
((unsigned int) (-((__ONE_COUNT__) != 0))) \
& (((unsigned int) -1) >> ((sizeof(unsigned int) * CHAR_BIT) - (__ONE_COUNT__)))
Let's focus on:
((sizeof(unsigned int) * CHAR_BIT)
first. sizeof(unsigned int) is known at compile time. It is equal to 4 according to our assumption. CHAR_BIT represents the number of bits per char, a.k.a. per byte. It is also known at compile time. It is equal to 8 on most machines on the Earth. Since this expression is known at a compile time, the compiler would probably do the multiplication at compile time and treat it as a constant, which equals to 32 in this case.
Let's move to:
((unsigned int) -1)
It is equal to 0xFFFFFFFF. Casting -1 to any unsigned type produces a value of "all-1s" in that type. This part is also a compile time constant.
Up to now, the expression:
(((unsigned int) -1) >> ((sizeof(unsigned int) * CHAR_BIT) - (__ONE_COUNT__)))
is in fact the same as:
0xffffffffUL >> (32 - param)
which is the same as Julien's answer above. One problem with his answer is that if param is equal to 0, producing the expression 0xffffffffUL >> 32, the result of the expression would be 0xffffffffUL, instead of the expected 0! (That's why I name my parameter as __ONE_COUNT__ to emphasize its intention)
To solve this problem, we could simply add a special case for __ONE_COUNT equals 0 using if-else or ?:, like this:
#define BIT_MASK(__TYPE__, __ONE_COUNT__) \
(((__ONE_COUNT__) != 0) \
? (((__TYPE__) -1) >> ((sizeof(__TYPE__) * CHAR_BIT) - (__ONE_COUNT__)))
: 0)
But branch-free code is cooler, isn't it?! Let's move to the next part:
((unsigned int) (-((__ONE_COUNT__) != 0)))
Let's start from the innermost expression to the outermost. ((__ONE_COUNT__) != 0) produces 0 when the parameter is 0, or 1 otherwise. (-((__ONE_COUNT__) != 0)) produces 0 when the parameter is 0, or -1 otherwise. For ((unsigned int) (-((__ONE_COUNT__) != 0))), the type-cast trick ((unsigned int) -1) is already explained above. Do you notice the trick now? The expression:
((__TYPE__) (-((__ONE_COUNT__) != 0)))
equals to "all-0s" if __ONE_COUNT__ is zero, and "all-1s" otherwise. It acts as a bit-mask for the value we calculated in the first step. So, if __ONE_COUNT__ is non-zero, the mask as no effect and it is the same as Julien's answer. If __ONE_COUNT__ is 0, it mask away all bits of Julien's answer, producing a constant zero. To visualize, watch this:
__ONE_COUNT__ : 0 Other
------------- --------------
(__ONE_COUNT__) 0 = 0x000...0 (itself)
((__ONE_COUNT__) != 0) 0 = 0x000...0 1 = 0x000...1
((__TYPE__) (-((__ONE_COUNT__) != 0))) 0 = 0x000...0 -1 = 0xFFF...F

Alternatively, you can use a right shift to avoid the issue mentioned in the (1 << param) - 1 solution.
unsigned long const mask = 0xffffffffUL >> (32 - param);
assuming that param <= 32, of course.

For those interested, this is the lookup-table alternative discussed in comments to the other answer - the difference being that it works correctly for a param of 32. It's easy enough to extend to the 64 bit unsigned long long version, if you need that, and shouldn't be significantly different in speed (if it's called in a tight inner loop then the static table will stay in at least L2 cache, and if it's not called in a tight inner loop then the performance difference won't be important).
unsigned long mask2(unsigned param)
{
static const unsigned long masks[] = {
0x00000000UL, 0x00000001UL, 0x00000003UL, 0x00000007UL,
0x0000000fUL, 0x0000001fUL, 0x0000003fUL, 0x0000007fUL,
0x000000ffUL, 0x000001ffUL, 0x000003ffUL, 0x000007ffUL,
0x00000fffUL, 0x00001fffUL, 0x00003fffUL, 0x00007fffUL,
0x0000ffffUL, 0x0001ffffUL, 0x0003ffffUL, 0x0007ffffUL,
0x000fffffUL, 0x001fffffUL, 0x003fffffUL, 0x007fffffUL,
0x00ffffffUL, 0x01ffffffUL, 0x03ffffffUL, 0x07ffffffUL,
0x0fffffffUL, 0x1fffffffUL, 0x3fffffffUL, 0x7fffffffUL,
0xffffffffUL };
if (param < (sizeof masks / sizeof masks[0]))
return masks[param];
else
return 0xffffffffUL; /* Or whatever else you want to do in this error case */
}
It's worth pointing out that if you need the if() statement (because are worried that someone might call it with param > 32), then this doesn't win you anything over the alternative from the other answer:
unsigned long mask(unsigned param)
{
if (param < 32)
return (1UL << param) - 1;
else
return -1;
}
The only difference is that the latter version has to special case param >= 32, whereas the former only has to special case param > 32.

How about this (in Java):
int mask = -1;
mask = mask << param;
mask = ~mask;
This way you can avoid lookup tables and hard coding the length of an integer.
Explanation: A signed integer with a value of -1 is represented in binary as all ones. Shift left the given number of times to add that many 0's to the right side. This will result in a 'reverse mask' of sorts. Then negate the shifted result to create your mask.
This could be shortened to:
int mask = ~(-1<<param);
An example:
int param = 5;
int mask = -1; // 11111111 (shortened for example)
mask = mask << param; // 11100000
mask = ~mask; // 00011111

From top of my head. Sorry, I'm on mobile. I assume a 64 bit type for clarity, but this can be easily generalized.
(((uint64_t) (bits < 64)) << (bits & 63)) - 1u
It's the typical (1 << bits) - 1 but branchless, with no undefined behavior, with the & 63 optimizable away on some platforms and with correct results for the whole range of values.
The left (left) shift operand becomes 0 for shifts bigger or equal than the type width.
The right (left) shift operand is masked to avoid undefined behavior, the value will never get bigger than 63. This is just to make compilers and language lawyers happy, as no platform will be adding ones when the left operand is already zero (for values bigger than 63). A good compiler should remove the & 63 masking on platforms where this is already the behavior of the underlying instruction (e.g. x86).
As we have seen, values bigger than 63 get a result of 0 from the shift, but there is a substraction by one afterwards leaving all bits set by an unsigned integer underflow, which is not undefined behavior on unsigned types.

If you're worried about overflow in a C-like language with (1 << param) - 1 (when param is 32 or 64 at the max size type the mask becomes 0 since bitshift pushes past the bounds of type), one solution I just thought of:
const uint32_t mask = ( 1ul << ( maxBits - 1ul ) ) | ( ( 1ul << ( maxBits - 1ul ) ) - 1ul );
Or another example
const uint64_t mask = ( 1ull << ( maxBits - 1ull ) ) | ( ( 1ull << ( maxBits - 1ull ) ) - 1ull );
Here's a templatized version, keep in mind that you should use this with an unsigned type R:
#include <limits.h> /* CHAR_BIT */
// bits cannot be 0
template <typename R>
static constexpr R bitmask1( const R bits )
{
const R one = 1;
assert( bits >= one );
assert( bits <= sizeof( R ) * CHAR_BIT );
const R bitShift = one << ( bits - one );
return bitShift | ( bitShift - one );
}
Let's say max bits is 8 with a byte, with the first overflowing function we'd have 1 << 8 == 256, which when cast to byte becomes 0. With my function we have 1 << 7 == 128, which a byte can contain, so becomes 1<<7 | 1<<7 - 1.
I haven't compiled the function, so it may contain typos.
And for fun here's Julien Royer's fleshed out:
// bits can be 0
template <typename R>
static constexpr R bitmask2( const R bits )
{
const R zero = 0;
const R mask = ~zero;
const R maxBits = sizeof( R ) * CHAR_BIT;
assert( bits <= maxBits );
return mask >> ( maxBits - bits );
}

For a 32-bit mask you can use this (use uint64_t for a 64-bit mask):
#include <assert.h>
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
int
main()
{
size_t n = 8;
assert(n <= 32);
uint32_t mask = ~(uint32_t)0 >> (32 - n);
printf("mask = %08" PRIX32 "\n", mask);
}
I know it's an answer to a very old post. But in case some human being actually reads this: I would welcome any feedback.

Just for reference (google), I used the following to get an all 1 mask for for integral types.
In C++ one might simply use:
std::numeric_limits<uint_16t>::max() // 65535

Related

Most efficient way to set n consecutive bits to 1?

I want to get a function that will set the n last bits of a numerical type to 1. For example:
bitmask (5) = 0b11111 = 31
bitmask (0) = 0
I, first, had this implementation (mask_t is just a typedef around uint64_t):
mask_t bitmask (unsigned short n) {
return ((((mask_t) 1) << n) - 1;
}
Everything is fine except when the function hit bitmask (64) (the size of mask_t), then I get bitmask (64) = 0 in place of 64 bits set to 1.
So, I have two questions:
Why do I have this behavior ? Pushing the 1 by 64 shifts on the left should clear the register and remain with 0, then applying the -1 should fill the register with 1s...
What is the proper way to achieve this function ?
Yes this is a well known problem. There are easy ways to implement this function over the range 0..63 and over the range 1..64 (one way has been mentioned in the comments), but 0..64 is more difficult.
Of course you can just take either the "left shifting" or "right shifting" mask generation and then special-case the "missing" n,
uint64_t bitmask (unsigned short n) {
if (n == 64) return -((uint64_t)1);
return (((uint64_t) 1) << n) - 1;
}
Or
uint64_t bitmask (unsigned short n) {
if (n == 0) return 0;
uint64_t full = ~(uint64_t)0;
return full >> (64 - n);
}
Either way tends to compile to a branch, though it technically doesn't have to.
You can do it without if (not tested)
uint64_t bitmask (unsigned int n) {
uint64_t x = (n ^ 64) >> 6;
return (x << (n & 63)) - 1;
}
The idea here is that we're going to either shift 1 left by some amount the same as in your original code, or 0 in the case that n = 64. Shifting 0 left by 0 is just going to be 0 again, subtracting 1 sets all 64 bits.
Alternatively if you're on a modern x64 platform and BZHI is available, a very fast (BZHI is fast on all CPUs that implement it) but limited-portability option is:
uint64_t bitmask (unsigned int n) {
return _bzhi_u64(~(uint64_t)0, n);
}
This is even well-defined for n > 64, the actual count of 1's will be min(n & 0xFF, 64) because BZHI saturates but it reads only the lowest byte of the index.
You cannot left shift by a value larger than or equal to the bit width of the type in question. Doing so invokes undefined behavior.
From section 6.5.7 of the C standard:
2 The integer promotions are performed on each of the operands. The
type of the result is that of the promoted left operand. If the value
of the right operand is negative or is greater than or equal to the
width of the promoted left operand, the behavior is undefined.
You'll need to add a check for this in your code:
mask_t bitmask (unsigned short n) {
if (n >= 64) {
return ~(mask_t)0;
} else {
return (((mask_t) 1) << n) - 1;
}
}
Finally, just for your information, I ended up by writing:
mask_t bitmask (unsigned short n) {
return (n < (sizeof (mask_t) * CHAR_BIT)) ? (((mask_t) 1) << n) - 1 : -1;
}
But, the answer of harold is so complete and well explained that I will select it as the answer.

Insert bit into uint16_t

Is there any efficient algorithm that allows to insert bit bit to position index when working with uint16_t? I've tried reading bit-by-bit after index, storing all such bits into array of char, changing bit at index, increasing index, and then looping again, inserting bits from array, but could be there a better way? So I know how to get, set, unset or toggle specific bit, but I suppose there could be better algorithm than processing bit-by-bit.
uint16_t bit_insert(uint16_t word, int bit, int index);
bit_insert(0b0000111111111110, 1, 1); /* must return 0b0100011111111111 */
P.S. The solution must be in pure ANSI-compatible C. I know that 0b prefix may be specific to gcc, but I've used it here to make things more obvious.
Use bitwise operators:
#define BIT_INSERT(word, bit, index) \
(((word) & (~(1U << (index)))) | ((bit) << (index)))
#include <errno.h>
#include <stdint.h>
/* Insert a bit `idx' positions from the right (lsb). */
uint16_t
bit_insert_lsb(uint16_t n, int bit, int idx)
{
uint16_t lower;
if (idx > 15) {
errno = ERANGE;
return 0U;
}
/* Get bits 0 to `idx' inclusive. */
lower = n & ((1U << (idx + 1)) - 1);
return ((n & ~lower) | ((!!bit) << idx) | (lower >> 1));
}
/* Insert a bit `idx' positions from the left (msb). */
uint16_t
bit_insert_msb(uint16_t n, int bit, int idx)
{
uint16_t lower;
if (idx > 15) {
errno = ERANGE;
return 0U;
}
/* Get bits 0 to `16 - idx' inclusive. */
lower = n & ((1U << (15 - idx + 1)) - 1);
return ((n & ~lower) | ((!!bit) << (15 - idx)) | (lower >> 1));
}
Bits are typically counted from the right, where the least significant bit (lsb) resides, to the left, where the most significant bit (msb) is located. I allowed for insertion from either side by creating two functions. The one expected, according to the question, is bit_insert_msb.
Both functions perform a sanity check, setting errno to ERANGE and returning 0 if the value of idx is too large. I also provided some of C99's _Bool behaviour for the bit parameter in the return statements: 0 is 0 and any other value is 1. If you use a C99 compiler, I'd recommend changing bit's type to _Bool. You can then replace (!!bit) with bit directly.
I'd love to say it could be optimised, but that could very well make it less comprehensible.
Happy coding!
If you're counting bits from the left
mask = (1 << (16 - index + 1)) - 1; // all 1s from bit "index" to LSB
// MSB of word (from left to index) | insert bit at index | LSB of word from (index-1)
word = (word & ~mask) | (bit << (16 - index)) | ((word & mask) >> 1);
There may be many ways more efficient but this way it's easy to understand

How to get the fewest bytes required to store an integer value with macro?

For example,if the integer is less than 255,than it can be restored in 1 byte,
if it's greater than 255,it requires at lest 2 bytes.
How to write such a BYTES_REQUIRED(i) macro?
If you are using a C99 compiler make the cast below to (unsigned long long).
Also you can (and should) extend the construct to 8 or 16 bytes (that's left as an exercise)
#include <limits.h>
#define BYTES_REQUIRED(i) \
!((unsigned long)(i) >> CHAR_BIT) ? 1 \
: !((unsigned long)(i) >> 2 * CHAR_BIT) ? 2 \
: !((unsigned long)(i) >> 3 * CHAR_BIT) ? 3 \
: 4
This uses an efficient divide and conquer approach:
#define BYTES_REQUIRED(i) (((i) & 0xFFFF0000) ? (((i) & 0xFF000000) ? 4 : 3) : (((i) & 0xFF00) ? 2 : 1))
If you don't mind eliminating the odd case of 3 bytes, which has no primitive type that matches it, do:
#define BYTES_REQUIRED(i) (((i) & 0xFFFF0000) ? 4 : (((i) & 0xFF00) ? 2 : 1))
Be warned neither one of these handles negative numbers, since it sees the sign extended 1 bits as used space. This requires another conditional to account for (e.g. if negative, negate).
You effectively need to calculate log2(i). There's no trivial way of doing that portably, quickly, for the maximum integer value supported by the compiler and with a macro.
Options:
1.Calculate the logarithm in a loop:
// 64+-bit version:
unsigned long BYTES_REQUIRED(unsigned long long i)
{
unsigned long bits = 0;
while (i)
{
i >>= 1;
bits++;
}
if (bits == 0) bits = 1;
return (bits + 7) / 8; // we're assuming that byte=8 bits, but CHAR_BIT may be > 8
}
2.Use an intrinsic function (effectively, a dedicated CPU instruction) of the compiler, if available. For MSVC++:
// 64-bit version, not available for 32-bit code:
unsigned long BYTES_REQUIRED(unsigned long long i)
{
unsigned long index;
if (_BitScanReverse64(&index, i) == 0)
{
index = 1;
}
return (index + 8) / 8;
}
// 32-bit version, available for 32 and 64-bit code:
unsigned long BYTES_REQUIRED(unsigned long i)
{
unsigned long index;
if (_BitScanReverse(&index, i) == 0)
{
index = 1;
}
return (index + 8) / 8;
}
// 64-bit version available for 32 and 64-bit code:
unsigned long BYTES_REQUIRED(unsigned long long i)
{
unsigned long index;
if (_BitScanReverse(&index, (unsigned long)(i >> 32)))
{
index += 32;
}
else if (_BitScanReverse(&index, (unsigned long)i) == 0)
{
index = 1;
}
return (index + 8) / 8;
}
3.Use if or ?: knowing the size of the biggest supported integer type... Others have described this method already.
Unfortunately you asked for a C macro, because this C++ templated function could have been helpful (it should work for any integer type supported by your compiler).
template <typename T> int bytesRequired(T value) {
boost::function_requires< boost::IntegerConcept<T> >();
for (int i=0; i<=sizeof(T); i++, value/=256)
if (value == 0) return i;
}
Another approach that should be faster (because it's branchless), if you don't just need compile-time evaluation, is the bitscan that was mentioned by Alex.

How to tell if a 32 bit int can fit in a 16 bit short

Using only:
! ~ & ^ | + << >>
I need to find out if a signed 32 bit integer can be represented as a 16 bit, two's complement integer.
My first thoughts were to separate the MSB 16 bits and the LSB 16 bits and then use a mask to and the last 16 bits so if its not zero, it wont be able to be represented and then use that number to check the MSB bits.
An example of the function I need to write is: fitsInShort(33000) = 0 (cant be represented) and fitsInShort(-32768) = 1 (can be represented)
bool fits16(int x)
{
short y = x;
return y == x;
}
Just kidding :) Here's the real answer, assuming int is 32 bits and short is 16 bits and two's complement represantation:
Edit: Please see the last edit for the correct answer!
bool fits16(int x)
{
/* Mask out the least significant word */
int y = x & 0xffff0000;
if (x & 0x00008000) {
return y == 0xffff0000;
} else {
return y == 0;
}
}
Without if statements i beleive that should do it:
return (
!(!(x & 0xffff0000) || !(x & 0x00008000)) ||
!((x & 0xffff0000) || (x & 0x00008000))
);
Edit: Oli's right. I somehow thought that they were allowed. Here's the last attempt, with explanation:
We need the 17 most significant bits of x to be either all ones or all zeroes. So let's start by masking other bits out:
int a = x & 0xffff8000; // we need a to be either 0xffff8000 or 0x00000000
int b = a + 0x00008000; // if a == 0xffff8000 then b is now 0x00000000
// if a == 0x00000000 then b is now 0x00008000
// in any other case b has a different value
int c = b & 0xffff7fff; // all zeroes if it fits, something else if it doesn't
return c;
Or more concisely:
return ((x & 0xffff8000) + 0x8000) & 0xffff7fff;
If a 32-bit number is in the range [-32768,+32767], then the 17 msbs will all be the same.
Here's a crappy way of telling if a 3-bit number is all ones or all zeros using only your operations (I'm assuming that you're not allowed conditional control structures, because they require implicit logical operations):
int allOnes3(int x)
{
return ((x >> 0) & (x >> 1) & (x >> 2)) & 1;
}
int allTheSame3(int x)
{
return allOnes3(x) | allOnes3(~x);
}
I'll leave you to extend/improve this concept.
Here's a solution without casting, if-statements and using only the operators you asked for:
#define fitsInShort(x) !(((((x) & 0xffff8000) >> 15) + 1) & 0x1fffe)
short fitsInShort(int x)
{
int positiveShortRange = (int) ((short) 0xffff / (short) 2);
int negativeShortRange = (int) ((short) 0xffff / (short) 2) + 1;
if(x > negativeShortRange && x < positiveShortRange)
return (short) x;
else
return (short) 0;
}
if (!(integer_32 & 0x8000000))
{
/* if +ve number */
if (integer_32 & 0xffff8000)
/* cannot fit */
else
/* can fit */
}
else if (integer_32 & 0x80000000)
{
/* if -ve number */
if ( ~((integer_32 & 0xffff8000) | 0x00007fff))
/* cannot fit */
else
/* can fit */
}
First if Checks for +ve number first by checking the signed bit. If +ve , then it checks if the bit 15 to bit 31 are 0, if 0, then it cannot fit into short, else it can.
The negative number is withing range if bit 15 to 31 are all set (2's complement method representation).
Therefore The second if it is a -ve number, then the bit 15 to 31 are masked out and the remaining lower bits (0 to 14) are set. If this is 0xffffffff then only the one's complement will be 0, which indicates the bit 15 to 31 are all set, therefore it can fit (the else part), otherwise it cannot fit (the if condition).

Swap two bits with a single operation in C?

Let's say I have a byte with six unknown values:
???1?0??
and I want to swap bits 2 and 4 (without changing any of the ? values):
???0?1??
But how would I do this in one operation in C?
I'm performing this operation thousands of times per second on a microcontroller so performance is the top priority.
It would be fine to "toggle" these bits. Even though this is not the same as swapping the bits, toggling would work fine for my purposes.
Try:
x ^= 0x14;
That toggles both bits. It's a little bit unclear in question as you first mention swap and then give a toggle example. Anyway, to swap the bits:
x = precomputed_lookup [x];
where precomputed_lookup is a 256 byte array, could be the fastest way, it depends on the memory speed relative to the processor speed. Otherwise, it's:
x = (x & ~0x14) | ((x & 0x10) >> 2) | ((x & 0x04) << 2);
EDIT: Some more information about toggling bits.
When you xor (^) two integer values together, the xor is performed at the bit level, like this:
for each (bit in value 1 and value 2)
result bit = value 1 bit xor value 2 bit
so that bit 0 of the first value is xor'ed with bit 0 of the second value, bit 1 with bit 1 and so on. The xor operation doesn't affect the other bits in the value. In effect, it's a parallel bit xor on many bits.
Looking at the truth table for xor, you will see that xor'ing a bit with the value '1' effectively toggles the bit.
a b a^b
0 0 0
0 1 1
1 0 1
1 1 0
So, to toggle bits 1 and 3, write a binary number with a one where you want the bit to toggle and a zero where you want to leave the value unchanged:
00001010
convert to hex: 0x0a. You can toggle as many bits as you want:
0x39 = 00111001
will toggle bits 0, 3, 4 and 5
You cannot "swap" two bits (i.e. the bits change places, not value) in a single instruction using bit-fiddling.
The optimum approach if you want to really swap them is probably a lookup table. This holds true for many 'awkward' transformations.
BYTE lookup[256] = {/* left this to your imagination */};
for (/*all my data values */)
newValue = lookup[oldValue];
The following method is NOT a single C instruction, it's just another bit fiddling method. The method was simplified from Swapping individual bits with XOR.
As stated in Roddy's answer, a lookup table would be best. I only suggest this in case you didn't want to use one. This will indeed swap bits also, not just toggle (that is, whatever is in bit 2 will be in 4 and vice versa).
b: your original value - ???1?0?? for instance
x: just a temp
r: the result
x = ((b >> 2) ^ (b >> 4)) & 0x01
r = b ^ ((x << 2) | (x << 4))
Quick explanation: get the two bits you want to look at and XOR them, store the value to x. By shifting this value back to bits 2 and 4 (and OR'ing together) you get a mask that when XORed back with b will swap your two original bits. The table below shows all possible cases.
bit2: 0 1 0 1
bit4: 0 0 1 1
x : 0 1 1 0 <-- Low bit of x only in this case
r2 : 0 0 1 1
r4 : 0 1 0 1
I did not fully test this, but for the few cases I tried quickly it seemed to work.
This might not be optimized, but it should work:
unsigned char bit_swap(unsigned char n, unsigned char pos1, unsigned char pos2)
{
unsigned char mask1 = 0x01 << pos1;
unsigned char mask2 = 0x01 << pos2;
if ( !((n & mask1) != (n & mask2)) )
n ^= (mask1 | mask2);
return n;
}
The function below will swap bits 2 and 4. You can use this to precompute a lookup table, if necessary (so that swapping becomes a single operation):
unsigned char swap24(unsigned char bytein) {
unsigned char mask2 = ( bytein & 0x04 ) << 2;
unsigned char mask4 = ( bytein & 0x10 ) >> 2;
unsigned char mask = mask2 | mask4 ;
return ( bytein & 0xeb ) | mask;
}
I wrote each operation on a separate line to make it clearer.
void swap_bits(uint32_t& n, int a, int b) {
bool r = (n & (1 << a)) != 0;
bool s = (n & (1 << b)) != 0;
if(r != s) {
if(r) {
n |= (1 << b);
n &= ~(1 << a);
}
else {
n &= ~(1 << b);
n |= (1 << a);
}
}
}
n is the integer you want to be swapped in, a and b are the positions (indexes) of the bits you want to be swapped, counting from the less significant bit and starting from zero.
Using your example (n = ???1?0??), you'd call the function as follows:
swap_bits(n, 2, 4);
Rationale: you only need to swap the bits if they are different (that's why r != s). In this case, one of them is 1 and the other is 0. After that, just notice you want to do exactly one bit set operation and one bit clear operation.
Say your value is x i.e, x=???1?0??
The two bits can be toggled by this operation:
x = x ^ ((1<<2) | (1<<4));
#include<stdio.h>
void printb(char x) {
int i;
for(i =7;i>=0;i--)
printf("%d",(1 & (x >> i)));
printf("\n");
}
int swapb(char c, int p, int q) {
if( !((c & (1 << p)) >> p) ^ ((c & (1 << q)) >> q) )
printf("bits are not same will not be swaped\n");
else {
c = c ^ (1 << p);
c = c ^ (1 << q);
}
return c;
}
int main()
{
char c = 10;
printb(c);
c = swapb(c, 3, 1);
printb(c);
return 0;
}

Resources