当前位置:网站首页>In depth understanding of pre post + +, -- and negative modulus
In depth understanding of pre post + +, -- and negative modulus
2022-07-25 05:13:00 【Australopithecus northerner】
List of articles
Preface
This article mainly understands some pre post ++、- - Rules of use , First use ? How to use it first ; If there is no receiver , How is this first used and embodied ; We can understand the modulo operation of positive integers , Then think more deeply , How do negative numbers perform modulo operations ?
Next , I will discuss the above issues with you .
One 、++、- - First use ?
Before you know it , We may look at a little compilation to understand ;
1、 The difference between assigning initial value and assignment
First , Let's answer a question first , Whether the initial value and assignment are the same ?
…
Strictly speaking, it is different , But we often confuse these two concepts in our daily use , How is it different ? Let's understand it by assembly ;
int main()
{
int a = 10;// This is called the initial value
int b = 20;
b = a;// This is called assignment
return 0;
}

This is the assembly fragment corresponding to this code ;
Next , From the perspective of compilation , Explain it. , Why is the initial value assigned different from the assignment ;
In fact, from the perspective of compilation , We understand that assigning an initial value does not need to go through a register , Put data directly into the open space , This also shows that assigning initial values actually completes two things :1、 Open up space .2、 Assign values to the space .
Then let's take a look at assignment : Through the assembly instructions, we can see ,1、 Assignment does not need to open up space .2、 Assignment cannot be completed directly , It must be done through registers ;
The above is the difference between assigning initial value and assigning value ;
To sum up :
Assignment cannot be done directly , It must be done through registers ; But assigning initial value does not need register , It can be done directly ;
2、++、- -
Next, let's return to the theme ;
Test code :
int main()
{
int a = 4;
int b = 2;
b = a++;
return 0;
}
This code , You can see it at a glance b The value of becomes 4,a The value of becomes 5;
How to become ? Use it first and then add it ,a First use , That is, to b, And then add up ; You get the above results ;
This is a rough understanding , Next, let's understand the situation of the receiver from the perspective of assembly ;
This is the assembly corresponding to the above code ; Let me explain next ;
( First of all, increase by yourself , Reuse , The same is true )
Now let's talk about , Without receiving and releasing , Use this first ( Or how post use is embodied ;)
Test code :
int main()
{
int a = 1;
a++;
return 0;
}

The corresponding assembly language ;
We can see from assembly language , Without the receiver , First use ( Or post use does not exist , No one will receive , Naturally, it is not used first ( Or assembly instructions used later , After the direct self increase , Just write it back to memory )
Empathy ++a The same is true ;
The overall effect is similar to a++ It's the same ;
To sum up :
For pre post ++、- - Come on , If there is a receiving party , Will execute first use ( Or post use operation ), For those without a receiver , It will directly increase itself ( Or self reducing ), No unnecessary operations , At the same time, the front ++、- - And post ++、- - Can achieve the same effect ;
3、“ classic ” error
Let's have a look first , The following code :
int main()
{
int a = 1;
int b = 1;
b = (++a) + (++a) + (++a);
printf("%d\n",b);
return 0;
}
You can guess , This running result :
The answer is that this code has no definite result , Under different compilers , The results are different ;
stay VS2019 in :
stay Dev In the environment :
On mobile phone :
Why does this happen , Next, we will start from the perspective of compilation (VS2019 In the environment ) To understand :
The reasons for the above results , Mainly due to , Compilers for various platforms , The above assembly code is interpreted in different ways ,( It can also be considered that the code itself is not rigorous , The way to calculate is not the only ), about VS2019 Come on , What he thinks is to first ++ After execution , In the a The value of is written back to memory , In execution + Method operation ; But some compilers , It may be done first 1、2 step , Writing to memory , Read into the register , In execution 3 step , Then I didn't reset a The value of is written into memory again , then , Then add , And that leads to this , In memory a Value , It's always the last value , The value in the register is the value after self increment , But it is not written back to memory , It will cause the mixed use of the last value and the refreshed value , It will result in different final running results ;
To sum up :
In our daily study and work , We should avoid writing such ambiguous code , Reduce output bug The probability and cost ;
Two 、 Negative modulo ?
In us C In language learning .% Operators are often used , It's also widely used ;
But if we pay enough attention , We'll find out , We met % operation , It seems that they are all aimed at positive numbers ;
For negative numbers % We don't seem to know so much about computation ;
Then let's have a detailed look ;
1、 Rounding method
Before going into the subject formally , We need to learn about : The way of rounding :
int a=3.14;
stay C We all know in language , The way to round is , Give up the decimal part , Take the integral part directly , Such as the above code ,a=3;
Is there only one rounding method ?
Of course not ! There is diversity in the world , Moreover, C Language ;
A、 towards 0 integer
What do you mean , It means :
Sketch Map :
When we round a decimal , We should try our best to 0 Round the direction of ;
What do you mean ? for instance :
-3.79 integer , Namely -3;
-3.1 integer , Namely -3;
3.9 integer , Namely 3;
Now I can probably understand ;
This rounding method , Just ask us to get close 0 Of , And an integer close to our decimal ;
B、 Rounding negative infinity
This rounding method is also well understood :
Sketch Map :
Take a chestnut :
-3.79 integer , Namely -4;
-3.1 integer , Namely -4;
3.9 integer , Namely 3;
Now I can probably understand ;
This rounding method , It requires us to take something close to negative infinity , And an integer close to our decimal ;
C、 Rounding to positive infinity
This is easy to understand :
Sketch Map :
Take a chestnut :
-3.79 integer , Namely -3;
-3.1 integer , Namely -3;
3.9 integer , Namely 4;
Now I can probably understand ;
This rounding method , It requires us to take the one close to positive infinity , And an integer close to our decimal ;
D、 Round to the nearest whole
This should be the most understandable .
Take a chestnut :
-3.79 integer , Namely -4;
-3.1 integer , Namely -3;
3.9 integer , Namely 4;
Write a code and feel the following overall :
#include<math.h>
int main()
{
float a, b, c, d, e;
a = 1.0f;
b = 2.1f;
c = -1.3f;
d = -0.2f;
e = 3.76f;
printf("f_val\ttrunc\tfloor\tceil\tround\n");
printf("%.1f\t%.1f\t%.1f\t%.1f\t%.1f\n", a, trunc(a), floor(a), ceil(a), round(a));
printf("%.1f\t%.1f\t%.1f\t%.1f\t%.1f\n", b, trunc(b), floor(b), ceil(b), round(b));
printf("%.1f\t%.1f\t%.1f\t%.1f\t%.1f\n", c, trunc(c), floor(c), ceil(c), round(c));
printf("%.1f\t%.1f\t%.1f\t%.1f\t%.1f\n", d, trunc(d), floor(d), ceil(d), round(d));
printf("%.1f\t%.1f\t%.1f\t%.1f\t%.1f\n", e, trunc(e), floor(e), ceil(e), round(e));
return 0;
}
Run a screenshot :
The header file :#include<math.h>
trunc() The function is directed to 0 integer ;
floor() The function is rounded to negative infinity ;
ceil() The function is rounded to positive infinity ;
round() The function is rounding ;
C The language is directed 0 integer ;
For example, in C In language
-3.14 Rounding is -3;
stay python Is rounded to negative infinity ;
stay python in -3.14 Rounding is -4;
2、 Talk about taking mold
Mold concept : If a and d It's a natural number ,d Not 0, It can be proved that there are two unique integers q and r, Satisfy a=q*d+r, And 0<=r<d, among q It's called business ,r It's called the remainder ;
Then let's take a look at the following code ;
among 10=(q)*3+(r)
According to the direction 0 Rounding principle ,q=3, so r=1;
What if it's negative ?
According to the above rules :
-10=(q)3+(r);
towards 0 Rounding principle :q=-3, so r=-1;
This seems to conflict with the above definition ,r<0 了 , To solve this problem , We revised the definition : If a and d It's a natural number ,d Not 0, It can be proved that there are two unique integers q and r, Satisfy a=qd+r, And 0<=|r|<|d|, among q It's called business ,r It's called the remainder ;
With this definition ,C In language r It can be explained by being negative ;
The above does not mean , stay python Is the rounding method different in ? that -10/3 And -10%3 Is the result the same ?
Through verification, it is found that the results are different :
analysis :-10/3 yes -3.33333…, Round to negative infinity ,-10/3 It should be -4;
Empathy :-10=(q)*3+(r);q=-4, so r=2;
3、 What determines this phenomenon ?
Through the analysis above , We come to the conclusion that
stay C In language ,-10%3=-1;
stay python in ,-10%3=2;
So what is the reason ? We know , The remainder is determined by quotient , What determines the quotient ? It's because of the rounding method ; stay C Language and python The difference in rounding method between the two , It's caused “ modulus ” The difference of ; That's why % Operator , In different languages , The meaning is different ;
4、 Is the mold the same as the remainder ?
Most of the time they mean the same thing , But strictly speaking, this is not the case :
modulus : The way to take quotient is to round it like negative infinity ;
Remainder : The way to get quotient is to follow the example 0 The way of rounding ;
about C language % It means taking the remainder ;
about python Come on % Representative mould ;
So how to judge a language % Does it represent remainder or module ?
You can use the following code to test :
C Language ( or C++) Under the language ,% Is a remainder operation ;
int main()
{
int a = -10;
int b = 3;
if (a / b == -3)
{
printf("%% Do the remainder operation \n");
printf("%d\n", a / b);
}
else
{
printf("%% Modulo operation done \n");
printf("%d\n",a/b);
}
return 0;
}

边栏推荐
- Ping command
- [c language] custom type (structure ~ enumeration ~ Union)
- Learn to use PHP to get the URL address link after resetting
- China trifluoroethanol industry research and investment forecast report (2022 Edition)
- harbor安装
- 自己实现is_convertible
- Nexttick principle analysis
- 微信小程序相关操作示例
- STL notes (VI): container vector
- Implementation principle of epoll
猜你喜欢

I will write some Q & A blogs recently, mainly focusing on the points that are easy to have doubts.

Ora-01460: conversion request cannot be implemented or unreasonable

How to ensure data consistency between MySQL and redis?

Three must know and know problems of redis

Xiaohongshu joins hands with HMS core to enjoy HD vision and grow grass for a better life
![2022-07-24: what is the output of the following go language code? A:[]int{}; B:[]int(nil); C:panic; D: Compilation error. package main import ( “fmt“ ) f](/img/bf/e38a8fd813f88a83f61a1abfa3b95d.png)
2022-07-24: what is the output of the following go language code? A:[]int{}; B:[]int(nil); C:panic; D: Compilation error. package main import ( “fmt“ ) f
![[literature notes] pointmlp](/img/8f/654dc6e2f4770b7f12aab49098d3d7.png)
[literature notes] pointmlp

Redis的三个必知必会的问题

Panda3D keyboard moving scene

Basic knowledge of scratch crawler framework
随机推荐
服务器防护的七个建议
如何判断是否遭到DDOS攻击
China trifluoroethanol industry research and investment forecast report (2022 Edition)
[no title] 1
自己实现is_convertible
Valley p2420 let's XOR solution
2022-7-18 summary
Add click event to unity 3D object
956. Highest billboard pressure DP
HMS Core Discovery第16期直播预告|与虎墩一起,玩转AI新“声”态
Completed project series Tutorials - smart campus management system
Sword finger offer II 014. anagrams in strings
Small case of data analysis: visualize recruitment data and view the most needed technologies in the field~
Ora-01460: conversion request cannot be implemented or unreasonable
How to ensure data consistency between MySQL and redis?
Learning records [email protected] R & D effectiveness measurement indicators
Redis集群搭建(Windows)
panda3d 键盘移动场景
Unity LOD
Idea2021 installation