Is there's a similar to:
if((bitmap & BIT_WATER) && (bitmap & BIT_FIRE)) bitmap &= ~BIT_FIRE
or
if(bitmap & BIT_WATER) bitmap &= ~BIT_FIRE
In a single statement using only bitwise operations, removing the need of a comparation (if)?
I totally mean that if two flag, each completly opposite to the other, are set clear one of them.
You can avoid the bitmap & BIT_FIRE in the first case, since bitmap &= ~BIT_FIRE; will do nothing to the bitmap if BIT_FIRE is not set.
There is no "set bit X if bit Y is set" in an arbitrary way.
Of course, if you KNOW that, say, BIT_FIRE is one bit higher than BIT_WATER, you could do bitmap &= ~(BIT_WATER << 1), which will clear the "one bit higher than BIT_WATER".
Probably premature optimization, but you could do
bitmap &= ~((bitmap & BIT_WATER) * (BIT_FIRE/BIT_WATER)) & ~((bitmap & BIT_WATER) * (BIT_WATER/BIT_FIRE))
as long as BIT_FIRE and BIT_WATER are single bits (powers of 2). You probably also want bitmap to be unsigned to insure that the compiler can easily optimize this down to a single shift, two bitwise ands, and a complement.
Of course, a good compiler would optimize your original code down to the same 4 instructions with no branch.
edit
Of course, I realized the above is incorrect -- only works if BIT_FIRE > BIT_WATER.
So just stick with the original if and let the compiler optimize it...
Promoting my comment to an answer. Note, it uses multiplication, but maybe it will be still useful to you (code on ideone.com):
#include <iostream>
int main()
{
int long unsigned bitmap_with_water = 0xF300003F;
int long unsigned bitmap_without_water = 0xF300000F;
int long unsigned bit_fire = 0x03000000;
int long unsigned bit_water = 0x00000030;
bitmap_with_water &= ~(bit_fire * static_cast<bool>(bitmap_with_water & bit_water));
bitmap_without_water &= ~(bit_fire * static_cast<bool>(bitmap_without_water & bit_water));
std::cout << (void*)(bitmap_with_water) << "\t" << (void*)(bitmap_without_water) << std::endl;
return (0);
}
Program output:
0xf000003f 0xf300000f
If you need to write a general purpose clear_if_set(int test, int clear, int bitmap) then this answer is useless.
If this is a specialized function and you know the shift distance from fire to water:
int water = bitmap & BIT_WATER;
int shifted = water << WATER_TO_FIRE_LSHIFT; // for example
bitmap &= ~shifted;
One-liner:
bitmap &= ~((bitmap & BIT_WATER) << WATER_TO_FIRE_LSHIFT);
If using bit numbers instead of pre-shifted bit masks is acceptable:
bitmap &= ~(((bitmap >> SHIFT_WATER) & 1) << SHIFT_FIRE)
Assuming BIT_WATER and BIT_FIRE are not the same bit then
the truth table for
if(bitmap & BIT_WATER) bitmap &= ~BIT_FIRE
is (BIT_WATER, old BIT_FIRE, new BIT_FIRE)
0 0 0
0 1 1
1 0 0
1 1 0
So from a bit perspective that is
BIT_FIRE = (~BIT_WATER)&BIT_FIRE;
1 0 0
1 1 1
0 0 0
0 1 0
Since I dont know the gap between your two bits then something like this which is excessive.
newbit = ((~(bitmap>>BIT_WATER_BIT))&(bitmap>>BIT_FIRE_BIT))&1;
bitmap&=~BIT_FIRE;
bitmap|=newbit<<BIT_FIRE_BIT;
Assuming I didnt make a typo...Also which I assume can be simplified if you take advantage of the specific bit numbers and not do something generic (shift BIT_WATER bit over to land on BIT_FIRE rather than shift everything right then left again. May not make it simpler though.
if bit water bit is 7 and bit fire bit is 3
bitmap = (((~(bitmap>>4))>>4)&(1<<3))&bitmap;
Or maybe this
bitmap = (((bitmap&(~BIT_WATER))^BIT_WATER)>>4)&bitmap;
where >>4 is the direction and delta between BIT_WATER and BIT_FIRE. fill in the proper delta.
Related
This question already has answers here:
What's the best way to toggle the MSB?
(4 answers)
Closed 8 years ago.
If, for example, I have the number 20:
0001 0100
I want to set the highest valued 1 bit, the left-most, to 0.
So
0001 0100
will become
0000 0100
I was wondering which is the most efficient way to achieve this.
Preferrably in c++.
I tried substracting from the original number the largest power of two like this,
unsigned long long int originalNumber;
unsigned long long int x=originalNumber;
x--;
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
x++;
x >>= 1;
originalNumber ^= x;
,but i need something more efficient.
The tricky part is finding the most significant bit, or counting the number of leading zeroes. Everything else is can be done more or less trivially with left shifting 1 (by one less), subtracting 1 followed by negation (building an inverse mask) and the & operator.
The well-known bit hacks site has several implementations for the problem of finding the most significant bit, but it is also worth looking into compiler intrinsics, as all mainstream compilers have an intrinsic for this purpose, which they implement as efficiently as the target architecture will allow (I tested this a few years ago using GCC on x86, came out as single instruction). Which is fastest is impossible to tell without profiling on your target architecture (fewer lines of code, or fewer assembly instructions are not always faster!), but it is a fair assumption that compilers implement these intrinsics not much worse than you'll be able to implement them, and likely faster.
Using an intrinsic with a somewhat intellegible name may also turn out easier to comprehend than some bit hack when you look at it 5 years from now.
Unluckily, although a not entirely uncommon thing, this is not a standardized function which you'd expect to find in the C or C++ libraries, at least there is no standard function that I'm aware of.
For GCC, you're looking for __builtin_clz, VisualStudio calls it _BitScanReverse, and Intel's compiler calls it _bit_scan_reverse.
Alternatively to counting leading zeroes, you may look into what the same Bit Twiddling site has under "Round up to the next power of two", which you would only need to follow up with a right shift by 1, and a NAND operation. Note that the 5-step implementation given on the site is for 32-bit integers, you would have to double the number of steps for 64-bit wide values.
#include <limits.h>
uint32_t unsetHighestBit(uint32_t val) {
for(uint32_t i = sizeof(uint32_t) * CHAR_BIT - 1; i >= 0; i--) {
if(val & (1 << i)) {
val &= ~(1 << i);
break;
}
}
return val;
}
Explanation
Here we take the size of the type uint32_t, which is 4 bytes. Each byte has 8 bits, so we iterate 32 times starting with i having values 31 to 0.
In each iteration we shift the value 1 by i to the left and then bitwise-and (&) it with our value. If this returns a value != 0, the bit at i is set. Once we find a bit that is set, we bitwise-and (&) our initial value with the bitwise negation (~) of the bit that is set.
For example if we have the number 44, its binary representation would be 0010 1100. The first set bit that we find is bit 5, resulting in the mask 0010 0000. The bitwise negation of this mask is 1101 1111. Now when bitwise and-ing & the initial value with this mask, we get the value 0000 1100.
In C++ with templates
This is an example of how this can be solved in C++ using a template:
#include <limits>
template<typename T> T unsetHighestBit(T val) {
for(uint32_t i = sizeof(T) * numeric_limits<char>::digits - 1; i >= 0; i--) {
if(val & (1 << i)) {
val &= ~(1 << i);
break;
}
}
return val;
}
If you're constrained to 8 bits (as in your example), then just precalculate all possible values in an array (byte[256]) using any algorithm, or just type it in by hand.
Then you just look up the desired value:
x = lookup[originalNumber]
Can't be much faster than that. :-)
UPDATE: so I read the question wrong.
But if using 64 bit values, then break it apart into 8 bytes, maybe by casting it to a byte[8] or overlaying it in a union or something more clever. After that, find the first byte which are not zero and do as in my answer above with that particular byte. Not as efficient I'm afraid, but still it is at most 8 tests (and in average 4.5) + one lookup.
Of course, creating a byte[65536} lookup will double the speed.
The following code will turn off the right most bit:
bool found = false;
int bit, bitCounter = 31;
while (!found) {
bit = x & (1 << bitCounter);
if (bit != 0) {
x &= ~(1 << bitCounter);
found = true;
}
else if (bitCounter == 0)
found = true;
else
bitCounter--;
}
I know method to set more right non zero bit to 0.
a & (a - 1)
It is from Book: Warren H.S., Jr. - Hacker's Delight.
You can reverse your bits, set more right to zero and reverse back. But I do now know efficient way to invert bits in your case.
I need to come up with a function which takes a char and index of a set bit in it and isolates a string of 1's containing that bit.
i.e.
char isolate(unsigned char arg, int i);
For example:
isolate(221,2) would return 28 (11011101 >>> 00011100)
isolate(221,6) would return 192 (11011101 >>> 1100000)
A lookup table seems a clumsy solution as it would require ~256*8=2048 entries.
I am thinking of examining each individual bit to the left and right of the index:
char isolate(char arg, int i)
{
char result=0;
char mask = 1<<i;
for(char mask = 1<<i; arg & mask != 0; mask>>=1)
result |= mask;
for(char mask = 1<<i; arg & mask != 0; mask<<=1)
result |= mask;
return result;
}
But it also seems a bit ugly. How can I do any better than this?
That's a funny operation. The code you've written expresses it fairly well, so would you mind elaborating on how it's ugly?
The details I can see: Given that i expresses a bit number in arg, there's absolutely no point in i being a wider type. There's never a point in writing != 0 in a condition. You probably don't want to be redeclaring mask everywhere you use it, nor initializing it twice in a row.
As for the actual spreading bit mask, I can't think of a way that's more expressive, cleaner or efficient right now.
Warning: none of this was tested or even relevant*, but it may be interesting.
Isolating the rightmost run of 1s is easy, like this: x ^ (x & ((x|(x-1))+1)) (explanation below), so let's work with that.
First x|(x-1) smears the rightmost 1 to the right, adding 1 turns all those bits to 0 including the rightmost run of 1's, anding x with removes rightmost run of 1's, and finally, xoring that with x leaves just the rightmost run of 1s.
Then we just need to make sure that the range we're looking for is the rightmost one. That's less amenable to simple bitmath, but if there's Count Leading Zeros (clz), it's not too hard:
int shift = 32 - clz(~x & ((1 << i) - 1)); //replace 32 with word size
x = (x >> shift) << shift;
((1 << i) - 1) makes a mask of the part where the right-end of the run we're looking for could be in (it could also just miss the end, but that's ok), then clz looks for the first zero to the right of i in x, then the shifts remove the bits that we don't want to look at.
Apply the first formula, for isolating the rightmost run of 1s, to the result of that to get the run of ones where i was in. i had better be in some run, or things go sideways (more accurately, it would return the first run of 1s that starts at an index higher than i)
*: For this question, none of this really matters. A 2KB table is not a clumsy solution unless you only have a tiny amount of memory available, and even if that's the case, the input is so short that the loops aren't all that bad.
I want to constrain the value of a signed short variable between 0 and 4095, after which I take the most significant 8 bits as my final value for use elsewhere. Right now I'm doing it in a basic manner as below:
short color = /* some external source */;
/*
* I get the color value as a 16 bit signed integer from an
* external source I cannot trust. 16 bits are being used here
* for higher precision.
*/
if ( color < 0 ) {
color = 0;
}
else if ( color > 4095 ) {
color = 4095;
}
unsigned char color8bit = 0xFF & (color >> 4);
/*
* color8bit is my final value which I would actually use
* in my application.
*/
Is there any way this can be done using bit manipulation only, i.e. without using any conditionals? It might help quite a bit in speeding things up as this operation is happening thousands of time in the code.
The following won't help as it doesn't take care of edge cases such as negative values and overflows:
unsigned char color8bit = 0xFF & (( 0x0FFF & color ) >> 4 );
Edit: Adam Rosenfield's answer is the one which takes the correct approach but its incorrectly implemented. ouah's answer gives correct results but takes a different approach that what I originally intended to find out.
This is what I ended up using:
const static short min = 0;
const static short max = 4095;
color = min ^ (( min ^ color ) & -( min < color ));
color = max ^ (( color ^ max ) & -( color < max ));
unsigned char color8bit = 0xFF & (( 0x0FFF & color ) >> 4 );
Yes, see these bit-twiddling hacks:
short color = ...;
color = color ^ (color & -(color < 0)); // color = max(color, 0)
color = 4096 ^ ((color ^ 4096) & -(color < 4096)); // color = min(color, 4096)
unsigned char color8bit = 0xFF & (color >> 4);
Whether this actually turns out to be faster, I don't know -- you should profile. Most modern x86 and x86-64 chips these days support "conditional move" instructions (cmov) which conditionally store a value depending on the EFLAGS status bits, and optimizing compilers will often produce these instructions from ternary expressions like color >= 0 ? color : 0. Those will likely be fastest, but they won't run on older x86 chips.
You can do the following:
BYTE data[0x10000] = { ..... };
BYTE byte_color = data[(unsiged short)short_color];
In your days 64kb table is not something outrageous and may be acceptable. The number of assembler commands in this variant of code will be absolute minimum compared to other possible approaches.
short color = /* ... */
color = ((((!!(color >> 12)) * 0xFFF)) | (!(color >> 12) * color ))
& (!(color >> 15) * 0xFFF);
unsigned char color8bit = 0xFF & (color >> 4);
It assumes two's complement representation.
This has the advantage of not using any equality or relational operators. There are situations you want to avoid branches at all costs: in some security applications you don't want the attackers to perform branch predictions. Without branches (in embedded processors particularly) you can make your function run in constant time for all inputs.
Note that: x * 0xFFF can be further reduced to (x << 12) - x. Also the multiplication in (!(color >> 12) * color ) can also be further optimized as the left operand of * here is 0 or 1.
EDIT:
I add a little explanation: the expression above simply does the same as below without the use of the conditional and relational operators:
y = ((y > 4095 ? 4095 : 0) | (y > 4095 ? 0 : y))
& (y < 0 ? 0 : 4095);
EDIT2:
as #HotLicks correctly noted in his comment, the ! is still a conceptual branch. Nevertheless it can also be computed with bitwise operators. For example !!a can be done with the trivial:
b = (a >> 15 | a >> 14 | ... | a >> 1 | a) & 1
and !a can be done as b ^ 1. And I'm sure there is a nice hack to do it more effectively.
I assume a short is 16 bits.
Remove negative values:
int16_t mask=-(int16_t)((uint16_t)color>>15);//0xFFFF if +ve, 0 if -ve
short value=color&mask;//0 if -ve, colour if +ve
value is now between 0 and 32767 inclusive.
You can then do something similar to clamp the value:
mask=(uint16_t)(value-4096)>>15;//1 if <=4095, 0 if >4095
--mask;//0 if <=4095, 0xFFFF if >4095
mask&=0xFFF;//0 if <=4095, 4095 if >4095
value|=mask;//4095 if >4095, color if <4095
You could also easily vectorize this using Intel's SSE intrinsics. One 128-bit register would hold 8 of your short and there are functions to min/max/shift/mask all of them in parallel. In a loop the constants for min/max can be preloaded into a register. The pshufb instruction (part of SSSE3) will even pack the bytes for you.
I'm going to leave an answer even though it doesn't directly answer the original question, because in the end I think you'll find it much more useful.
I'm assuming that your color is coming from a camera or image scanner running at 12 bits, followed by some undetermined processing step that might create values beyond the 0 to 4095 range. If that's the case the values are almost certainly derived in a linear fashion. The problem is that displays are gamma corrected, so the conversion from 12 bit to 8 bit will require a non-linear gamma function rather than a simple right shift. This will be much slower than the clamping operation your question is trying to optimize. If you don't use a gamma function the image will appear too dark.
short color = /* some external source */;
unsigned char color8bit;
if (color <= 0)
color8bit = 0;
else if (color >= 4095)
color8bit = 255;
else
color8bit = (unsigned char)(255.99 * pow(color / 4095.0, 1/2.2));
At this point you might consider a lookup table as suggested by Kirill Kobelev.
This is somewhat akin to Tom Seddon's answer, but uses a slightly cleaner way to do the clamp above. Note that both Mr. Seddon's answer and mine avoid the issue of ouah's answer that shifting a signed value to the right is implementation defined behavior, and hence not guaranteed to work on all architenctures.
#include <inttypes.h>
#include <iostream>
int16_t clamp(int16_t value)
{
// clampBelow is 0xffff for -ve, 0x0000 for +ve
int16_t const clampBelow = -static_cast<int16_t>(static_cast<uint16_t>(value) >> 15);
// value is now clamped below at zero
value &= ~clampBelow;
// subtract 4095 so we can do the same trick again
value -= 4095;
// clampAbove is 0xffff for -ve, 0x0000 for +ve,
// i.e. 0xffff for original value < 4095, 0x0000 for original >= 4096
int16_t const clampAbove = -static_cast<int16_t>(static_cast<uint16_t>(value) >> 15);
// adjusted value now clamped above at zero
value &= clampAbove;
// and restore to original value.
value += 4095;
return value;
}
void verify(int16_t value)
{
int16_t const clamped = clamp(value);
int16_t const check = (value < 0 ? 0 : value > 4095 ? 4095 : value);
if (clamped != check)
{
std::cout << "Verification falure for value: " << value << ", clamped: " << clamped << ", check: " << check << std::endl;
}
}
int main()
{
for (int16_t i = 0x4000; i != 0x3fff; i++)
{
verify(i);
}
return 0;
}
That's a full test program (OK, so it doesn't test 0x3fff - sue me. ;) ) from which you can extract the clamp() routine for whatever you need.
I've also broken clamp out to "one step per line" for the sake of clarity. If your compiler has a half way decent optimizer, you can leave it as is and rely on the compiler to produce the best possible code. If your compiler's optimizer is not that great, then by all means, it can be reduced in line count, albeit at the cost of a little readability.
"Never sacrifice clarity for efficiency" -- Bob Buckley, comp sci professor, U-Warwick, Coventry, England, 1980.
Best piece of advice I ever got. ;)
Hello is have a question for a school assignment i need to :
Read a round number, and with the internal binaire code with bit 0 on the right and bit 7 on the left.
Now i need to change:
bit 0 with bit 7
bit 1 with bit 6
bit 2 with bit 5
bit 3 with bit 4
by example :
if i use hex F703 becomes F7C0
because 03 = 0000 0011 and C0 = 1100 0000
(only the right byte (8 bits) need to be switched.
The lession was about bitmanipulation but i can't find a way to make it correct for al the 16 hexnumbers.
I`am puzzling for a wile now,
i am thinking for using a array for this problem or can someone say that i can be done with only bitwise ^,&,~,<<,>>, opertors ???
Study the following two functions:
bool GetBit(int value, int bit_position)
{
return value & (1 << bit_position);
}
void SetBit(int& value, int bit_position, bool new_bit_value)
{
if (new_bit_value)
value |= (1 << bit_position);
else
value &= ~(1 << bit_position);
}
So now we can read and write arbitrary bits just like an array.
1 << N
gives you:
000...0001000...000
Where the 1 is in the Nth position.
So
1 << 0 == 0000...0000001
1 << 1 == 0000...0000010
1 << 2 == 0000...0000100
1 << 3 == 0000...0001000
...
and so on.
Now what happens if I BINARY AND one of the above numbers with some other number Y?
X = 1 << N
Z = X & Y
What is Z going to look like? Well every bit apart from the Nth is definately going to be 0 isnt it? because those bits are 0 in X.
What will the Nth bit of Z be? It depends on the value of the Nth bit of Y doesn't it? So under what circumstances is Z zero? Precisely when the Nth bit of Y is 0. So by converting Z to a bool we can seperate out the value of the Nth bit of Y. Take another look at the GetBit function above, this is exactly what it is doing.
Now thats reading bits, how do we set a bit? Well if we want to set a bit on we can use BINARY OR with one of the (1 << N) numbers from above:
X = 1 << N
Z = Y | X
What is Z going to be here? Well every bit is going to be the same as Y except the Nth right? And the Nth bit is always going to be 1. So we have set the Nth bit on.
What about setting a bit to zero? What we want to do is take a number like 11111011111 where just the Nth bit is off and then use BINARY AND. To get such a number we just use BINARY NOT:
X = 1 << N // 000010000
W = ~X // 111101111
Z = W & Y
So all the bits in Z apart from the Nth will be copies of Y. The Nth will always be off. So we have effectively set the Nth bit to 0.
Using the above two techniques is how we have implemented SetBit.
So now we can read and write arbitrary bits. Now we can reverse the bits of the number just like it was an array:
int ReverseBits(int input)
{
int output = 0;
for (int i = 0; i < N; i++)
{
bool bit = GetBit(input, i); // read ith bit
SetBit(output, N-i-1, bit); // write (N-i-1)th bit
}
return output;
}
Please make sure you understand all this. Once you have understood this all, please close the page and implement and test them without looking at it.
If you enjoyed this than try some of these:
http://graphics.stanford.edu/~seander/bithacks.html
And/or get this book:
http://www.amazon.com/exec/obidos/ASIN/0201914654/qid%3D1033395248/sr%3D11-1/ref%3Dsr_11_1/104-7035682-9311161
This does one quarter of the job, but I'm not going to give you any more help than that; if you can work out why I said that, then you should be able to fill in the rest of the code.
if ((i ^ (i >> (5 - 2))) & (1 >> 2))
i ^= (1 << 2) | (1 << 5);
Essentially you need to reverse the bit ordering.
We're not going to solve this for you.. but here's a hint:
What if you had a 2-bit value. How would you reverse these bits?
A simple swap would work, right? Think about how to code this swap with operators that are available to you.
Now let's say you had a 4-bit value. How would you reverse these bits?
Could you split it into two 2-bit values, reverse each one, and then swap them? Would that give you the right result? Now code this.
Generalizing that solution to the 8-bit value should be trivial now.
Good luck!
I have a 5 byte data element and I need some help in figuring out how in C++ to set an individual bit of one of these byte; Please see my sample code below:
char m_TxBuf[4];
I would like to set bit 2 to high of byte m_TxBuf[1].
00000 0 00
^ This one
Any support is greatly appreciated;
Thanks!
Bitwise operators in C++.
"...set bit 2..."
Bit endianness.
I would like to set bit 2 to high of byte m_TxBuf[1];
m_TxBuf[1] |= 1 << 2
You can use bitwise-or (|) to set individual bits, and bitwise-and (&) to clear them.
int bitPos = 2; // bit position to set
m_TxBuf[1] |= (1 << bitPos);
m_TxBuf[1] |= 4;
To set a bit, you use bitwise or. The above uses compound assignment, which means the left side is one of the inputs and the output.
Typically we set bits using bitwise operator OR (operator| or operator|= as a shorthand).
Assuming 8-bits to a byte (where the MSB is considered the '7st' bit and the LSB considered the 0th: MSB 0) for simplicity:
char some_char = 0;
some_char |= 1 << 0; // set the 7th bit (least significant bit)
some_char |= 1 << 1; // set the 6th bit
some_char |= 1 << 2; // set the 5th bit
// etc.
We can write a simple function:
void set_bit(char& ch, unsigned int pos)
{
ch |= 1 << pos;
}
We can likewise test bits using operator&.
// If the 5th bit is set...
if (some_char & 1 << 2)
...
You should also consider std::bitset for this purpose which will make your life easier.
Just use std::bitset<40> and then index bits directly.