C deep profile "modulo rounding"

content

One: Four rounds

        1.1, 0-direction rounding

        1.2. Floor rounding (-∞ rounding)

        1.3, +∞ rounding

        1.4, rounding off

        1.5. Example summary

Two: modulo / remainder

        2.1. Concept

        2.2. Examples (C and Python)

        2.3. Is taking the remainder the same as taking the modulo?

        2.4. Calculated data with the same sign

        2.5. Different symbols of calculation data

        2.6. Summary


One: Four rounds

        1.1, 0-direction rounding

Look at the code:

#include <stdio.h>
int main()
{
	//本质是向0取整
	int i = -2.9;
	int j = 2.9;
	printf("%d\n", i); //结果是:-2
	printf("%d\n", j); //结果是:2
    printf("%d %d\n", 5 / 2, -5 / 2);  // 2 -2
	return 0;
}

The default 0-direction rounding in C, the drawing explains the 0-direction rounding:

 There is a trunc function in C language, which also uses 0-direction rounding. Note the reference header file #include<math.h>. An example is as follows:

#include <stdio.h>
#include<math.h>
int main()
{
	int i = -2.9;
	int j = 2.9;
	printf("%d\n", i); //结果是:-2
	printf("%d\n", j); //结果是:2
	printf("%d\n", (int)trunc(2.9)); //结果是:2 //结果是:-2
	printf("%d\n", (int)trunc(-2.9));//结果是:-2
	return 0;
}

        1.2, -∞ rounding (floor rounding)

In fact, the floor function is used, which is the same as the above trunc reference #include<math.h>

Look at the code:

#include<stdio.h>
#include<math.h>
int main()
{
	printf("%.1f\n", floor(-2.9)); // -3.0
	printf("%.1f\n", floor(-2.1)); // -3.0
	printf("%.1f\n", floor(2.9));  // 2.0
	printf("%.1f\n", floor(2.1));  // 2.0
	return 0;
}

Drawing explanation - ∞ rounding

        1.3, +∞ rounding

The ceil function is used, which also requires #include<math.h>

Look at the code:

#include<stdio.h>
#include<math.h>
int main()
{
	printf("%.1f\n", ceil(-2.9));  // -2.0
	printf("%.1f\n", ceil(-2.1));  // -2.0
	printf("%.1f\n", ceil(2.9));   // 3.0
	printf("%.1f\n", ceil(2.1));   // 3.0
	return 0;
}

Drawing explanation + ∞ rounding:

        1.4, rounding off

The round function is used, which also requires #include<math.h>

Look at the code:

#include<stdio.h>
#include<math.h>
int main()
{
	printf("%.1f\n", round(-2.9)); // -3.0
	printf("%.1f\n", round(-2.1)); // -2.0
	printf("%.1f\n", round(2.9));  // 3.0
	printf("%.1f\n", round(2.1));  // 2.0
}

        1.5. Example summary

#include <stdio.h>
#include <math.h>
int main()
{
	const char* format = "%.1f \t%.1f \t%.1f \t%.1f \t%.1f\n";
	printf("value\tround\tfloor\tceil\ttrunc\n");
	printf("-----\t-----\t-----\t----\t-----\n");
	printf(format, 2.3, round(2.3), floor(2.3), ceil(2.3), trunc(2.3));
	printf(format, 3.8, round(3.8), floor(3.8), ceil(3.8), trunc(3.8));
	printf(format, 5.5, round(5.5), floor(5.5), ceil(5.5), trunc(5.5));
	printf(format, -2.3, round(-2.3), floor(-2.3), ceil(-2.3), trunc(-2.3));
	printf(format, -3.8, round(-3.8), floor(-3.8), ceil(-3.8), trunc(-3.8));
	printf(format, -5.5, round(-5.5), floor(-5.5), ceil(-5.5), trunc(-5.5));
	return 0;
}

 in conclusion:

There are many rounding methods for floating point numbers (integer/integer).

Two: modulo / remainder

        2.1. Concept

If a and d are two natural numbers and d is nonzero, it can be shown that there are two unique integers q and r such that a = q*d + r and 0 ≤ r < d. where q is called the quotient and r is called the remainder.

        2.2. Examples (C and Python)

#include <stdio.h>
int main()
{
	int a = 10;
	int d = 3;
	printf("%d\n", a % d); //结果是1
	//因为:a=10,d=3,q=3,r=1 0<=r<d(3)
	//所以:a = q*d+r -> 10=3*3+1

	int m = -10;
	int n = 3;
	printf("%d\n", m / n); //C语言中是-3,很好理解
	printf("%d\n", m % n); //C语言是-1

	return 0;
}

In C language , we understand -10/3=-3 and -10%3=-1 well, there is no dispute

In Python , -10/3 = -4 , and -10%3 = 2

why?

Conclusion: Obviously, the above definition of modulo does not satisfy the language modulo operation

Parse:

Because in C, negative numbers appear in -10%3, according to the definition: satisfy a = q*d + r and 0 ≤ r < d, the remainder in C language does not satisfy the definition, because r<0 .

Therefore, we have a revised definition of modulo: If a and d are two natural numbers, and d is non-zero, it can be proved that there are two unique integers q and r, satisfying a = q*d + r, q is Integer with 0 ≤ |r| < |d|. where q is called the quotient and r is called the remainder.

With this new definition, "modulo" in C or Python can be explained.

Explanation C: -10 = (-3) * 3 + (-1)

Explain Python: -10 = (?) * 3 + 2, which can be pushed out, '?' must be -4 (later verification). That is -10 = (-4) * 3 + 2, in order to meet the definition.

Therefore, in different languages, the same calculation expression, the "modulo" result of a negative number is different. We can call them positive remainder and negative remainder respectively

What determines this phenomenon?

It can be seen from the above example that the size of the specific remainder r essentially depends on the quotient q.

And business, who depends on it? Depends on the rounding rules when dividing.

        2.3. Is taking the remainder the same as taking the modulo?

Careful classmates, you should have seen that the modulo above me are all marked with "". It shows that these two are not strictly equivalent (although most of the cases are similar). Take the remainder or the modulo, you should calculate the quotient, and then you can get the remainder.

Essential 1 rounding:

Remainder: Make the quotient as much as possible and round to 0.

Modulo: Make the quotient as much as possible, rounding in the direction of -∞.

Therefore:

The % in C is actually a remainder.

% in Python is actually a modulo.

Understanding the chain:

For any number greater than 0, perform 0 rounding and -∞ rounding on it, and the rounding direction is consistent. Therefore, taking the modulo is equivalent to taking the remainder. For any number less than 0, it is rounded in the direction of 0 and -∞, and the rounding direction is opposite. So taking the modulo is not equivalent to taking the remainder

The quotient obtained by dividing the data with the same sign must be a positive number (positive number vs positive integer), that is, greater than 0! Therefore, when rounding its quotient, taking the modulo is equivalent to taking the remainder.

Essence 2 notation:

The two data involved in the remainder, if they have the same sign, the modulo is equivalent to taking the remainder

        2.4. Calculated data with the same sign

Look at the code:

#include <stdio.h>
int main()
{
	printf("%d\n", 10 / 3);  // 3
	printf("%d\n\n", 10 % 3);// 1
	printf("%d\n", -10 / -3); // 3
	printf("%d\n\n", -10 % -3); // -1
	return 0;
}

In Python, we find that the result is the same as above.

Conclusion: Through the comparative test, it is more verified that if the two data involved in taking the remainder, if the sign is the same, taking the modulo is equivalent to taking the remainder

        2.5. Different symbols of calculation data

Look at the code:

#include <stdio.h>
int main()
{
	printf("%d\n", -10 / 3); //结果:-3
	printf("%d\n\n", -10 % 3); //结果:-1 为什么? -10=(-3)*3+(-1)
	printf("%d\n", 10 / -3); //结果:-3
	printf("%d\n\n", 10 % -3); //结果:1 为什么?10=(-3)*(-3)+1
	return 0;
}

In Python, the result is not like this.

Obvious conclusion: If the sign is different, the method of finding the remainder, refer to the previous definition. The remainder sign is the same as the dividend.

why?

Re-look at the definition: if a and d are two natural numbers and d is nonzero, it can be shown that there are two unique integers q and r such that a = q*d + r , q is an integer, and 0 ≤ |r| < |d|. where q is called the quotient and r is called the remainder

a = q*d + r transforms into r = a - q*d transforms into r = a + (-q*d)

For: x = y + z, such an expression, the sign of x is consistent with the large data in |y|, |z|

In r = a + (-q*d), the absolute value of |a| and |-q*d| depends on how the quotient q is rounded.

c is rounded to 0, that is, the absolute value of q itself is reduced. Such as:

-10/3=-3.333.33 round to 0 -3. a=-10 |10|, -q*d=-(-3)*3=9 |9|

10/-3=-3.333.33 rounds to 0 -3. a=10 |10|, -q*d=-(-3)*(-3)=-9 |9|

The absolute value has decreased

Python is rounded to -∞, that is, the absolute value of q itself is increased.

-10/3=-3.333.33 '//' round to -∞ -4. a=-10 |10|, -q*d=-(-4)*3=12 |12|

10/-3=--3.333.33 '//' Round up to -∞ by -4. a=10 |10|, -q*d=-(-4)*(-3)=-12 |12|

The absolute value has increased

Conclusion: If the two data symbols involved in the remainder are different, in the C language (or other languages ​​that use rounding to 0, such as C++, Java), the remainder symbol is the same as the dividend.

        2.6. Summary

(1) There are many rounding methods for floating point numbers (or integer division).

(2) If a and d are two natural numbers, and d is non-zero, it can be proved that there are two unique integers q and r, satisfying a = q*d + r , q is an integer, and 0 ≤ |r| < |d |. where q is called the quotient and r is called the remainder.

(3) In different languages, the same calculation expression, the result of "modulo" is different. We can call them positive remainder and negative remainder respectively

(4) The size of the specific remainder r essentially depends on the quotient q. The quotient, in turn, depends on the rounding rules when dividing.

(5) Remainder vs modulo: Take the remainder as much as possible to make the quotient, and round to 0. Take the modulo as much as possible to make the quotient, and round to the -∞ direction.

(6) If the two data involved in taking the remainder have the same sign, taking the modulo is equivalent to taking the remainder

(7) If the two data symbols involved in the remainder are different, in the C language (or other languages ​​that use rounding to 0, such as C++, Java), the remainder symbol is the same as the dividend. (because it is rounded to 0)

Guess you like

Origin blog.csdn.net/bit_zyx/article/details/122414209