[Link to this article]
Http://www.cnblogs.com/hellogiser/p/special-expressions.html
- The meaning of the x & (x-1) expression: count the number of 1 in binary.
C ++ Code
1 2 3 4 5 6 7 8 9 10 11 |
|
Int func (int x) { Int countx = 0; While (x) { Countx ++; X = x & (x-1 ); } Return countx; }
|
Assume that x = 9999 is 10011100001111.
Answer: 8
Train of Thought: Convert x to a binary system and check the number of contained 1.
Note: each time x = x & (x-1) is executed, a 1 on the rightmost side of x is changed to 0 when x is represented in binary, because the X-1 will change this bit (A 1 on the rightmost when x is represented in binary) to 0.
- The (x & y) + (x ^ y)> 1) function is to take the average value of two numbers (x + y)/2.
The function of (x & y) + (x ^ y)> 1) is to take the average value of two numbers (x + y)/2 is awesome, although not efficient, this method does not produce high overflow if it is in assembly.
The general idea should be as follows: x = x1 + x2 + x3, y = y1 + y2 + y3. (x + y)/2 = (x1 + y1) /2 + (x2 + y2)/2 + (x3 + y3)/2. divide each of the corresponding bits (Binary bits) in x and y into three types, calculate the average value for each class, and summarize the results. Where, the first class is x, and the corresponding bits of y are all 1, and the average value of x & y is calculated. The first class is x, and the corresponding bits of y have and only one bits are 1, use (x ^ y)> 1 to calculate the average value, and the other is x. The corresponding bits in y are both 0, and 0 is calculated.
Next I will explain how the first two cases are calculated:
1) In the first part, the corresponding bits of x and y are both 1. After adding them, divide them by 2 or the original number. For example, if two 00001111 bits are added and then divided by 2, they still get 00001111.
2) In the second part, the corresponding bits of x and y have only one bits of 1 and are extracted using the "XOR" operation. Then> 1 (Shifts one bit to the right, equals to dividing by 2), that is, the average to the second part.
3) in the third part, the corresponding bits of x and y are all zero. Because the sum is divided by two or 0, no calculation is required.
4) after the three parts are summarized, they are (x & y) + (x ^ y)> 1 ).
By the way, we can avoid overflow. Assume that x and y are unsigned char data (0 ~ 255, occupies one byte). Obviously, the average of x and y is also 0 ~ Between 255, but if x + y is used directly, the result may exceed 255, which results in overflow. Although the final result is within 255, the overflow must be handled in the process, in assembly, you need to consider this high overflow situation. If (x & y) + (x ^ y)> 1), the calculation will not.
C ++ Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
// Return half of sum of x and y Unsigned char half (unsigned char x, unsigned char y) { Return (x & y) + (x ^ y)> 1 ); // Return (x + y)/2; // may be overflow }
Void test_half () { Printf ("% d \ n", half (2, 8); // 5 Printf ("% d \ n", half (5, 5); // 5 Printf ("% d \ n", half (5, 6); // 5 Printf ("% d \ n", half (255,255); /// 255 } |
- (Int &) Difference between a and (int)
C ++ Code
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Void test_a () { // (Int &) a treat a memory as a integer Float a = 1.0f; Cout <(int) a <endl; // 1 Cout <(int &) a <endl; /// 1065353216 Cout <boolalpha <(int) a = (int &) a) <endl; // false
Float B = 0.0f; Cout <(int) B <endl; // 0 Cout <(int &) B <endl; // 0 Cout <boolalpha <(int) B = (int &) B) <endl; // true } |
(Int) a actually constructs an integer with the floating point a as the parameter. The value of this integer is 1.
(Int &) a tells the compiler to treat a as an integer (no substantial conversion is done ). Because 1 is stored as an integer and its memory data is stored as a floating point, the two are not the same.
The two conversions of B are the same, but the integer form of 0 is the same as that of floating point, so in this special case, the two are equal (only in numerical sense ).
Note: the output of the program will show (int &) a = 1065353216. How does this value come from? As mentioned above, 1 is stored in the memory as a floating point number. According to ieee754, the content of 1 is 0x0000803F (Bytes reverse order has been considered ). This is the value of the memory unit occupied by the variable. When (int &) a appears, it is equivalent to telling its context: "treat this address as an integer! Don't worry about what it was ." In this way, the content 0x0000803F is interpreted as an integer, and its value is exactly 1065353216 (decimal number ).
[Link to this article]
Http://www.cnblogs.com/hellogiser/p/special-expressions.html