C/C ++ division implementation method and negative number modulo (From Baidu)

Source: Internet
Author: User

1. Can you do all of the following?
1.7/4 =?
2.7/(-4) =?
3.7% 4 =?
4.7% (-4) =?
5. (-7)/4 =?
6. (-7) % 4 =?
7. (-7)/(unsigned) 4 =?
If you have all the correct answers, you can ignore the following content ......

Ii. Division round Classification
There are three types of Division integers: rounded up, rounded down, and rounded down.
1. rounded up: returns an integer closest to the exact value in the + ∞ direction. In this round, 7/4 =/(-4) =-/3 =/(-3) =-2
2. rounded down: returns an integer nearest to the exact value in the-∞ direction. In this round, 7/4 =/(-4) =-/3 =/(-3) =-2
3. rounded to zero: an integer closest to the exact value in the 0 direction. In other words, it is used to remove the decimal part. Therefore, it is also called truncation and integer. In this round, 7/4 =/(-4) =-/3 =/(-3) =-2
Through observation, we can find that (-a)/B =-(a/B) is not necessarily true, whether it is rounded up or down. This brings great trouble to program designers. For an integer to zero, (-a)/B =-(a/B) is true. In this way, C/C ++ uses this round.

Iii. Negative number modulo
Recall the formula of primary school: divisor = Operator ...... Remainder.
From this we can see that the remainder = divisor-Quotient × divisor (*)
For C/C ++, the (*) method is still valid. In addition, this formula is the key to solving the negative number modulo problem.
Example 1: 7% (-4) =?
Solution: It can be seen from the division method rounded to zero by C/C ++, 7/(-4) =-1; known by the (*) formula, remainder = 7-(-4) * (-1) = 3. so 7% (-4) = 3
Example 2: (-7) % 4 =?
Solution: It can be seen from the division method rounded to zero in C/C ++, (-7)/4 =-1; known by the (*) formula, remainder = (-7) -4 * (-1) =-3. therefore, (-7) % 4 =-3
Example 3: (-7) % (-4) =?
Solution: It can be seen from the division method rounded to zero by C/C ++, (-7)/(-4) = 1; known by the (*) formula, remainder = (-7)-(-4) * 1 =-3. therefore, (-7) % (-4) =-3

Iv. Development of relevant knowledge
1. for division between signed integers and unsigned integers, C/C ++ converts signed integers to unsigned integers. Note that the symbols are not lost, instead, the data bit is involved in the operation. This is why (-7)/(unsigned) 4 is not equal to-1, but 1073741822.
2. Compiler Optimization of Division
① Under the "no optimization" condition, the compiler will perform simple Optimization on the Division without affecting normal debugging.
A. Division of the "constant/constant" type: the compiler calculates the result directly.
B. Division of the variable type: No optimization.
C. Variable/constant division: If the constant is equal to 2 ^ n, NO optimization is performed. Otherwise, the Division is converted to the right shift operation. Because the Division implemented by the right shift operation is actually rounded down, the compiler will convert the downward round to zero round without generating the branch structure through some additional commands.

Take variable/2 ^ 3 as an example. The disassembly code is as follows:
Mov eax, Divisor
Cdq; If eax is <0, edx = 0 xFFFFFFFF; otherwise, edx = 0
And edx, 7; If eax <0, edx = 7; otherwise, edx = 0
Add eax, edx; If eax is <0, [(eax + 7)/(2 ^ 3)], the value is rounded down to [eax/(2 ^ 3)] returns an equal value to zero to achieve an integer to zero.
SAR eax, 3; right shift, complete division
② Under the "O2 optimization" condition, in the division of the "variable/constant" type, if the constant is 2 ^ N, it can also be optimized. In this case, division is converted into a combination of multiplication and right shift. For example, a/B = A * (1/B) = A * (2 ^ N)/B) * (1/(2 ^ n), where, (2 ^ N)/B is magicnumber, which is calculated by the compiler during compilation. In this way, a/B becomes (A * magicnumber)> N, and the value of N is selected by the compiler. It should be noted that this formula is only a typical representative of Division optimization. the compiler will adjust the formula according to the divisor, but the basic form is similar to the principle.

Address: http://tieba.baidu.com/p/1881961036


The following is an excerpt from C ++ primer (p130)

Operator % is called the "remainder" or "modulo" operator. The operand of this operator can only be an integer.

If the two operands are positive, the result is also positive. If both operands are negative, the result is negative. If one operand is positive, and the other operand is negative, the modulo result is dependent on the machine.

When one of the operands is negative and the other is positive, the symbol used to evaluate the result value of the modulo operation can be determined by the symbol of the numerator (divisor) or denominator (divisor. If the modulo result is followed by the numerator symbol, the calculated value is rounded to the zero side. If the modulo matches the denominator symbol, then the value is rounded to the negative infinity side.

(VC seems to be the symbol used to determine the modulo operation based on the left operand)

Related Article

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.