Returns a mysterious constant. [0x077cb531] is used to calculate the number of digits with 0 at the end of the binary.

Source: Internet
Author: User

You may remember a piece of tianshu-like code in quake III.
, The mysterious constant 0x5f3759df used in this article is actually a headache for many people. Today, I see a piece of code that is just as weird.
The following bitwise computation tips can quickly show the number of zeros at the end of a Binary Expression of a number. For example, the Binary Expression of 123 456 is 1 11100010 01000000, so the result of this program is 6.

unsigned int v;  // find the number of trailing zeros in 32-bit v
int r;           // result goes here
static const int MultiplyDeBruijnBitPosition[32] =
{
  0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
  31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
};
r = MultiplyDeBruijnBitPosition[((uint32_t)((v & -v) * 0x077CB531U)) >> 27];

Familiar with bit operations
Friends
It can be recognized that V &-V is used to retrieve the right consecutive 0 and the first occurrence 1. When v = 123 456, V &-V
It is equal to 64, that is, 1000000 of the binary. It's strange. What is 0x077cb531? Array
What is multiplydebruijnbitposition?

This must begin with a property of 0x077cb531. Write this constant as a 32-bit binary.

00000111011111001011010100110001

This 01 string has a very good place for B: If we think of it as a loop, it exactly contains all 32 possible 5-bit 01
String, no duplicates, no omissions! In fact, such a 01 string is not uncommon, because constructing such a 01 string is equivalent to finding the Euler in a directed graph.
Loop. For example, construct a graph with 16 vertices named 0000,000 1, 0010,…, respectively ,..., 1111. If the last 3
Which is equal to the first three digits of another vertex. Draw an arrow pointing from the former to the latter. That is to say, as long as the number on the two vertices satisfies the relationship between ABCD and bcde (a, B
C, D, and E may represent the same number.) the path from ABCD to bcde is recorded as ABCDE.
. Note that some vertices can reach each other (such as 1010 and 0101), and some vertices can even reach their own path (such as 0000 ).

Constructing a string that contains all the possible five-digit 01 substrings is equivalent to walking along the arrow in the middle. Assume that the string is 0000
. If the next digit is 1, the substring 00001 is included, and the latest 4-digit number is 0001. However, if the next digit is 0
00000 is included, and the latest 4 numbers are still 0000. As shown in the figure, this is nothing more than a question about the route from:
00001 this road has reached the point of 0001, or it has gone back 00000 along the road of 0000.
This point. Similarly, every time you add a number, it is equivalent to entering a new point along a certain path. The five digits written on the road are the five digits that have just been taken into account.
Number of digits. Our goal is to traverse all paths without repetition or omission. Obviously, the inbound and outbound degrees of each vertex in the graph are both 2, so this graph must have
Loop, we can easily construct a 01 string that meets the requirements. Such a 01 string is called the de Bruijn sequence.

What is the use of the De Bruijn sequence here? Its purpose is actually very simple. It provides a unique index for 32 different cases. For example, if 1000000 is followed by six zeros and 1000000 is multiplied by 0x077cb531

   00000111011111001011010100110001
-> 11011111001011010100110001000000

It is equivalent to moving the de Bruijn sequence six places to the left. Moving this number right to 27 places is equivalent to extracting the first five digits of this number:

   11011111001011010100110001000000
->                            11011

Because of the nature of the De Bruijn sequence, when the number 0 at the end of the input number is different, the 5-digit number obtained at the end is also different. Array
Multiplydebruijnbitposition is equivalent to a dictionary function. 11011 is converted to decimal 27, So let's check
Multiplydebruijnbitposition [27], and the program returns 6.
Note that when the number of zeros at the end of the input number exceeds 27, the program is also correct, because the left-shift low position is filled with 0.

This magical code from http://graphics.stanford.edu /~ Seander/bithacks.html
Welcome to watching.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.