What is the meaning of >>= in C or C++? - c++

What is the meaning of the >>= symbol in C or C++? Does it have any particular name?
I have this for loop in some CUDA code which looks like this
for(int offset=blockDim.x; offset>0; offset >>=1)
{
//Some code
}
How does the offset variable get modfied with the >>= operator?

The >>= symbol is the assignment form of right-shift, that is x >>= y; is short for x = x >> y; (unless overloaded to mean something different).
Right shifting by 1 is equivalent to divide by 2. That code looks like someone doesn't trust the compiler to do the most basic optimizations, and should be equivalent to:
for( int offset = blockDim.x; offset > 0; offset /= 2 ){ ... }
More information about bitwise operations here:
http://en.wikipedia.org/wiki/Binary_shift#Bit_shifts

Literally offset = offset >> 1, that is, offset divided by 2

That's the assignment version of right shift:
foo >>= 2; // shift the bits of foo right by two places and assign the result to foo

it's a bitwise shift right operator. it shifts the bits of the variable to right by the value of right operand.

Related

The fastest way to swap the two lowest bits in an unsigned int in C++

Assume that I have:
unsigned int x = 883621;
which in binary is :
00000000000011010111101110100101
I need the fastest way to swap the two lowest bits:
00000000000011010111101110100110
Note: To clarify: If x is 7 (0b111), the output should be still 7.
If you have few bytes of memory to spare, I would start with a lookup table:
constexpr unsigned int table[]={0b00,0b10,0b01,0b11};
unsigned int func(unsigned int x){
auto y = (x & (~0b11)) |( table[x&0b11]);
return y;
}
Quickbench -O3 of all the answers so far.
Quickbench -Ofast of all the answers so far.
(Plus my ifelse naive idea.)
[Feel free to add yourself and edit my answer].
Please do correct me if you believe the benchmark is incorrect, I am not an expert in reading assembly. So hopefully volatile x prevented caching the result between loops.
I'll ignore the top bits for a second - there's a trick using multiplication. Multiplication is really a convolution operation, and you can use that to shuffle bits.
In particular, assume the two lower bits are AB. Multiply that by 0b0101, and you get ABAB. You'll see that the swapped bits BA are the middle bits.
Hence,
x = (x & ~3U) | ((((x&3)*5)>>1)&3)
[edit] The &3 is needed to strip the top A bit, but with std::uint_32_t you can use overflow to lose that bit for free - multiplication then gets you the result BAB0'0000'0000'0000'0000'0000'0000'0000'0000' :
x = (x & ~3U) | ((((x&3)*0xA0000000)>>30));
I would use
x = (x & ~0b11) | ((x & 0b10) >> 1) | ((x & 0b01) << 1);
Inspired by the table idea, but with the table as a simple constant instead of an array. We just need mask(00)==00, mask(01)==11, mask(10)=11, masK(11)==11.
constexpr unsigned int table = 0b00111100;
unsigned int func(unsigned int x) {
auto xormask = (table >> ((x&3) * 2)) &3;
x ^= xormask;
return x;
}
This also uses the xor-trick from dyungwang to avoid isolating the top bits.
Another idea, to avoid stripping the top bits. Assume x has the bits XXXXAB, then we want to x-or it with 0000(A^B)(A^B). Thus
auto t = x^(x>>1); // Last bit is now A^B
t &=1; // take just that bit
t *= 3; // Put in the last two positions
x ^= t; // Change A to B and B to A.
Just looking from a mathematical point of view, I would start with a rotate_left() function, which rotates a list of bits one place to the left (011 becomes 110, then 101, and then back 011), and use this as follows:
int func(int input){
return rotate_left(rotate_left((input / 4))) + rotate_left(input % 4);
}
Using this on the author's example 11010111101110100101:
input = 11010111101110100101;
input / 4 = 110101111011101001;
rotate_left(input / 4) = 1101011110111010010;
rotate_left(rotate_left(input / 4) = 11010111101110100100;
input % 4 = 01;
rotate_left(input % 4) = 10;
return 11010111101110100110;
There is also a shift() function, which can be used (twice!) for replacing the integer division.

Getting the index of the leftmost active bit in an integer instantly [duplicate]

This question already has answers here:
Minimum number of bits to represent a given `int`
(9 answers)
Closed 4 months ago.
How would I scan an integer (in binary) from left to right instead of right to left? I know that I can start from the left and try every bit, and then record the leftmost bit, but is there a faster way? Is there a built-in function that can instantly find the leftmost active bit (that is a 1) in an integer?
I know that for right to left, I can do something like
int myInt = 1234;
for(int i = 0; i < 32; i++) {
int curr_bit = myInt & (1 << i);
// do something with curr_bit
}
But, I want to start off at the leftmost available bit, and I want its number "x" so that 1 << x will point to that exact digit
(Just as a side note, I am trying to implement repeated squaring, and I need this in my code).
Any help would be greatly appreciated!
If you're interested in the actual fastest answer (at least on a desktop), here it is: use the _bit_scan_reverse intrinsic supported by Intel Compiler and Clang (maybe Visual Studio and GCC as well).
#include "immintrin.h"
int main() { printf("%i", _bit_scan_reverse(9)); }
Result: 3 (because 1<<3 = 8 is the highest bit set in 9).
Documentation
If you're worried about portability (as you should be with all proprietary extensions like this one), just include a fallback function and use the preprocessor to select the implementation you need:
#ifdef __SSE__ // All SSE processors support bsf/bsr
#include "immintrin.h"
static inline int bit_scan_reverse(int n) { return _bit_scan_reverse(n); }
#else
// Fallback implementation here
#endif
Note that the _bit_scan_reverse returns an unspecified value for n=0. If this is a problem you can add a ternary to the code in bit_scan_reverse: return n == 0 ? 0 : _bit_scan_reverse(n);.
This is called Find first set and most modern architectures have an instruction to do that quickly. In C++20 it can be done with std::countl_zero in the <bit> header
int left_most_bit_pos = sizeof(myInt)*CHAR_BIT - std::countl_zero(myInt);
int left_most_bit = myInt & (1 << left_most_bit_pos)
Java has a method in the Integer class called highestOneBit(int value) which returns an int value with at most a single one-bit, in the position of the most significant (left most) bit that is set in the specified int value. It is implemented like this:
int highestOneBit(int value)
{
value |= (value >> 1);
value |= (value >> 2);
value |= (value >> 4);
value |= (value >> 8);
value |= (value >> 16);
return value - (value >> 1);
}
iBug's answer is very interesting, and I had never thought of doing it this way. If you're doing huge calculations where you want to find the leftmost digit many many times, I would recomment __builtin_clz in c++11. If you perform the snippet
for(int i = 31 - __builtin_clz; i >= 0; i--) {
int left_most_bit = myInt & (1 << i);
}
This will start from the left_most_bit and work it's way to the right. Hope this helps!
Implementation of __builtin_clz
Use this:
int left_most_bit = myInt & (1 << (sizeof myInt * CHAR_BIT - 1));
How does it work?
sizeof myInt returns the size of the variable myInt in bytes
CHAR_BIT is a (possibly) platform-dependent macro that tells you how many bits are there in a byte, which is typically 8
Shift 1 left by that gets the leftmost bit.
Works great in O(1) time because both sizeof myInt and CHAR_BIT are compile-time constants, so the whole expression (1 << (sizeof myInt * CHAR_BIT - 1)) is a compile-time constant, too. The compiler can then apply maximum optimization to it.

implemenation of sets using bits

I am reading about sets representing as bits at following location
http://www.brpreiss.com/books/opus4/html/page395.html
class SetAsBitVector : public Set
{
typedef unsigned int Word;
enum { wordBits = bitsizeof (Word) };
Array<Word> vector;
public:
SetAsBitVector (unsigned int);
// ...
};
SetAsBitVector::SetAsBitVector (unsigned int n) :
Set (n),
vector ((n + wordBits - 1U) / wordBits)
{
// Question here?
for (unsigned int i = 0; i < vector.Length (); ++i)
vector [i] = 0;
}
void SetAsBitVector::Insert (Object& object)
{
unsigned int const item = dynamic_cast<Element&> (object);
vector [item / wordBits] |= 1 << item % wordBits;
// Question here
}
To insert an item into the set, we need to change the appropriate bit
in the array of bits to one. The ith bit of the bit array is bit i mod
w of word ceiling(i/w). Thus, the Insert function is implemented using
a bitwise or operation to change the ith bit to one as shown in above
Program . Even though it is slightly more complicated than the
corresponding operation for the SetAsArray class, the running time for
this operation is still O(1). Since w = wordBits is a power of two, it
is possible to replace the division and modulo operations, / and %,
with shifts and masks like this:
vector [item >> shift] |= 1 << (item & mask);
Depending on the compiler and machine architecture, doing so may
improve the performance of the Insert operation by a constant factor
Questions
My question in constructor why author adding wordBits to "n" and subtracting 1, instead we can use directly as n/wordbits?
Second question whay does author mean by statement "ince w = wordBits is a power of two, it is possible to replace the division and modulo operations, / and %, with shifts and masks like this:
vector [item >> shift] |= 1 << (item & mask);
Reequest to give an example in case of above scenario what is value of shift and mask.
Why author mentioned depending on architecture and compiler there is improve in performance?
I re-tagged this as C++, since it's clearly not C.
To round up. Consider what happens if you call it with n equal to something smaller than wordBits for instance. The generic formula is exactly the one being used, i.e. b = (a + Q - 1) / Q makes sure b * Q is at least a.
Basic binary arithmmetic, division by two is equivalent with shifting to the right and so on.
On some machines, bitwise operations like shifts and masks are faster than divisions and modulos.

Convert F to FF using left shift operator

I have UINT64 variable. In start it is initialized to 0xF. Now I want this to change on runtime depending on some input. Its value will increase on runtime. But what I want is that it should change from F to FF, from FF to FFF, one F should be appended to it.
Now here is my code.
UINT64 mapFileSize = 0xF;
while (mapFileSize < someUserInput)
// add one F to mapFileSize;
What should I write there. I am trying left shift operator but it is not working fine.
mapFileSize <<= 1;
I am doing this but this does not give me desired result.
leftshift mapFileSize 4 bit
and then or the mapFileSize with 0xF
mapFileSize = mapFileSize <<4;
mapFileSize = mapFileSize | 0xF;
What you're describing is not the result of a single shift. A << just shifts the bits, shifting in zeros as needed, but you would need to shift in ones which is something C's left-shift operator just doesn't do.
You need to first shift, and then set the lowest four bits to all ones:
mapFileSize <<= 4; /* Shift to the left one hexadecimal digit. */
mapFileSize |= 0xf; /* Make sure rightmost digit is f. */
A more succinct way of doing it:
mapFileSize |= (mapFileSize << 4);
Or if you can't guarantee that the original value always ends in 0xf:
mapFileSize = (mapFileSize << 4) | 0x0f;
$F$ shifted left by four is $0F0$, not $FF$. So you need:
mapFileSize <<= 4 ;
mapFileSize += 0x0F ;

Implementing logical shifts

I need to implement a bitwise shift (logical, not arithmetic) on OpenInsight 8.
In the system mostly everything is a string but there are 4 functions that treat numbers as 32-bit integers. The bitwise functions available are AND, OR, NOT and XOR. Any arithmetic operators treat the number as signed.
I'm currently having a problem with implementing left and right shifts which I need to implement SHA-1.
Can anyone suggest an algorithm which can help me accomplish this? Pseudocode is good enough, I just need a general idea.
You can implement shifting with integer multiplication and division:
Shift left = *2
Shift right = /2
Perhaps you need to mask the number first to make the most siginificant bit zero to prevent integer overflow.
logical shift down by one bit using signed arithmetic and bitwise ops
if v < 0 then
v = v & 0x7fffffff // clear the top bit
v = v / 2 // shift the rest down
v = v + 0x40000000 // set the penultimate bit
else
v = v / 2
fi
If there's no logical right shift you can easily achieve that by right shifting arithmetically n bits then clear the top n bits
For example: shift right 2 bits:
x >= 2;
x &= 0x3fffffff;
Shift right n bits
x >= n;
x &= ~(0xffffffff << (32 - n));
// or
x >= n;
x &= (1 << (32 - n)) - 1;
For left shifting there's no logical/mathematical differentiation because they are all the same, just shift 0s in.