What does >> and 0xfffffff8 mean?

I was told that (i >> 3) is faster than (i/8) , but I can not find any information about that >> . Can someone point me to a link that explains this?

The same person told me: " int k = i/8 , and then k*8 performs better (i&0xfffffff8); " but again Google did not help m ...

Thanks for any links!

+6
source share
11 answers

As explained here, the >> operator is simply a bitwise bit offset of i . Therefore, a shift of 1 bit to the right leads to an integer division by 2 and a shift of 3 bits leads to a division by 2 ^ 3 = 8.

But at present, this optimization for dividing by two forces should no longer be performed anymore, since compilers must be smart enough to do it themselves.

Similarly, bitwise AND with 0xFFFFFFF8 (1 ... 1000, the last 3 bits of 0) is equal to rounding down i to the nearest multiple of 8 (for example, (i/8)*8 ), since it will be zero the last 3 bits of i .

+9
source

Bitwise shift to the right. i >> 3 moves i integer 3 places to the right [binary path] - otherwise, divide by 2^3 .

+2
source

int x = i / 8 * 8:

1) i / 8, can be replaced with i → 3 - bitwise shift to the right by 3 digits (8 = 2 ^ 3)

2) me and xfffffff8 comparison with a mask For example, you have:

 i = 11111111 k (i/8) would be: 00011111 x (k * 8) would be: 11111000 

Therefore, the operation simply resets the last 3 bits: And the comparable time multiplication and division of the operation can simply be rewritten with

i and xfffffff8 - comparison with (... 11111000 mask)

+2
source

Regarding the first half:

>> is a bitwise shift to the right.

Thus, a shift of a numerical value of 3 bits to the right will be the same as dividing by 8 and int by the result.

Here is a good link for operators and their priority: http://web.cs.mun.ca/~michael/c/op.html

The second part of your question is related to the & operator, which is a bit-muddy I. Example: ANDing i and a number that leaves all the bits except the three least significant. This is essentially the same thing when you have a number, divide it by 8, save the result as an integer, then multiply this result by 8.

The reason for this is that dividing by 8 and storing as an integer is the same as shifting bits to the right 3 places, and multiplying by 8 and storing the result in int is the same as shifting bits to the left 3 places.

So, if you multiply or divide by 2, for example 8, and you agree with the truncation of bits that occur when you store this result in int , the bit shift is faster, faster. This is because the processor can skip the multiplication / division algorithm and just go to the offset bits, which includes several steps.

+1
source
+1
source

The >> operator is a bit shift operator. It takes the bit represented by the value and shifts them to the right number of slots.

+1
source

Bit offset

Suppose I have an 8 bit integer, in binary

01000000

If I left the shift (→) 1 operator, the result

00100000

If I then shift to the right (<<operator) 1, I will obviously return to the nose, I started

01000000

It turns out that since the first binary integer is equivalent

0 * 2 ^ 7 + 1 * 2 ^ 6 + 0 * 2 ^ 5 + 0 * 2 ^ 4 + 0 * 2 ^ 3 + 1 * 2 ^ 2 + 0 * 2 ^ 1 + 0 * 2 ^ 0

or just 2 ^ 6 or 64

When we right shift 1 we get the following

0 * 2 ^ 7 + 0 * 2 ^ 6 + 1 * 2 ^ 5 + 0 * 2 ^ 4 + 0 * 2 ^ 3 + 1 * 2 ^ 2 + 0 * 2 ^ 1 + 0 * 2 ^ 0

or just 2 ^ 5 or 32

What does it mean

 i >> 1 

coincides with

 i / 2 

If we move again ( i >> 2 ), we again divide by 2 and get

 i / 2 / 2 

Oh really

 i / 4 

Not entirely mathematical proof, but you can see that the following holds true:

 i >> n == i / (2^n) 
+1
source

>> right shift operation .

If you have number 8, which is represented in binary format as 00001000, shifting bits to the right by 3 positions will give you 00000001, that is, decimal 1. This is equivalent to dividing by 2 times.

Dividing and multiplying by the same number means that you set some bits on the right to zero. The same thing can be done if you apply a mask. Let's say 0xF8 is 11111000 bitwise, and if you And this number, it will set the last three bits to zero, and the remaining bits will remain as they are. For example, 10 and 0xF8 will be 00001010 and 11111000, which is equal to 00001000 or 8 in decimal form.

Of course, if you use 32-bit variables, you should have a mask corresponding to this size, so it will have all the bits set to 1, except for the three bits on the right, giving you your number - 0xFFffFFf8.

0
source

Moving bits in binary format like this:

1000 == 8

0100 == 4 (→ 1)

0010 == 2 (→ 2)

0001 == 1 (→ 3)

Since you are using the base system, you can take advantage of some dividers (only integers) and just reset the bit. In addition, I believe that most compilers know this and will do it for you.

Regarding the second part:

(i & 0xfffffff8);

Say i = 16

0x00000010 and 0xfffffff8 == 16

(16/8) * 8 == 16

Again the use of logical operators in binary format. Learn how logical operators work a bit more on a binary disk to really understand what happens at the bit level (and how to read hex).

0
source

This is called bit offset, it is an operation on bits, for example, if you have a binary base number, say 8, it will be 1000, so

 x = 1000; y = x >> 1; //y = 100 = 4 z = x >> 3; //z = 1 
0
source

>> shifts the number to the right. Consider the binary number 0001000 , which represents 8 in decimal notation. Shifting it 3 bits to the right will give 0000001 , which is the number 1 in decimal notation. Thus, you see that each shift of 1 bit to the right is actually a division by 2. Note that the operator truncates the float part of the result. Therefore, i >> n follows i/2^n . This can be fast depending on the compiler implementation. But this usually happens right in the registers and therefore very fast compared to traditional division and multiplication.

The answer to the second part is contained in the first. Since division also truncates the entire float part of the result, division by 8 will in theory shift your number 3 to the right, thereby losing all information about the rightmost 3 bits. Now, when you multiply it again by 8 (which theoretically means a left shift of 3 bits), you add the righmost 3 bits to zero after shifting the result remaining by 3 bits. Therefore, the complete operation can be considered as one "&" with 0xfffffff8 , which means that the number has all bits 1, with the exception of the rightmost 4 bits, which are 1000 .

0
source

Source: https://habr.com/ru/post/898998/


All Articles