本文已参与「新人创作礼」活动,一起开启掘金创作之路
目录
前言
本文主要讲解并真正理解取余\取模运算是怎样的!
取整
首先取整有四种类型:
- 向0取整
- 向-∞取整
- 向+∞取整
- 四舍五入取整
向0取整
- 示例:
int main()
{
//本质是向0取整
int i = -2.9;
int j = 2.9;
printf("%d\n", i); //结果是:-2
printf("%d\n", j); //结果是:2
return 0;
}
注:运行结果并不是像我们想的四舍五入数学取整,在C语言中本质是向0取整
当然对于向0取整我们也可以使用trunc库函数 (需包含math.h头文件)
- 示例:
#include <stdio.h>
#include <math.h> //使用了trunc函数,需要添加该头文件
int main()
{
//本质是向0取整,注意输出格式
printf("%.1f\n", trunc(-2.9)); //-2
printf("%.1f\n", trunc(-2.1)); //-2
printf("%.1f\n", trunc(2.9)); //2
printf("%.1f\n", trunc(2.1)); //2
return 0;
}
向-∞取整
这里我们需要floor库函数(需包含math.h头文件)
- 示例:
#include <stdio.h>
#include <math.h> //因为使用了floor函数,需要添加该头文件
int main()
{
//本质是向-∞取整,注意输出格式
printf("%.1f\n", floor(-2.9)); //-3
printf("%.1f\n", floor(-2.1)); //-3
printf("%.1f\n", floor(2.9)); //2
printf("%.1f\n", floor(2.1)); //2
return 0;
}
向+∞取整
这里我们需要ceil库函数(同样是math.h头文件)
- 示例:
#include <stdio.h>
#include <math.h>
int main()
{
//本质是向+∞取整,注意输出格式
printf("%.1f\n", ceil(-2.1)); //-2
printf("%.1f\n", ceil(2.9)); //3
printf("%.1f\n", ceil(2.1)); //3
return 0;
}
四舍五入取整
这里我们需要round库函数(math.h头文件)
- 示例:
#include <stdio.h>
#include <math.h>
int main()
{
//本质是四舍五入,同样注意输出格式
printf("%.1f\n", round(2.1));
printf("%.1f\n", round(2.9));
printf("%.1f\n", round(-2.1));
printf("%.1f\n", round(-2.9));
return 0;
}
汇总
#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;
}
- 输出结果:
结论:浮点数(整数/整数),是有很多的取整方式的
取模\余
- 定义:
如果a和d是两个自然数,d非零,可以证明存在两个唯一的整数 q 和 r
满足 a = q*d + r 且0 ≤ r < d。其中,q 被称为商,r 被称为余数
对于正数取模
- 示例:
int main()
{
int a = 10;
int d = 3;
printf("%d\n", a%d); //结果是1 (c,python结果相同)
//因为:a=10,d=3,q=3,r=1 0<=r<d(3)
//所以:a = q*d+r -> 10=3*3+1
return 0;
}
对于负数取模
- 示例:
int main()
{
int a = -10;
int d = 3;
printf("%d\n", a/d); //C语言中是-3,python是-4
printf("%d\n", a%d);//C语言中是-1,python是2
return 0;
}
为什么就有差异了呢?
- 解释:
C : - 10 = ( - 3 ) * 3 + ( - 1 )
Python : - 10 = ( - 4 ) * 3 + 2
- 从上看出:
具体余数r的大小,本质是取决于商q的,而取商取决于取证规则
由此对于负数“取模”结果的不同,我们分别称之为正余数和负余数
取余和取模的理解
取余:尽可能让商,进行向0取整
取模:尽可能让商,向-∞方向取整
从而C中%,本质其实是取余;Python中%,本质其实是取模
对任何一个大于0的数,对其进行0向取整和-∞取整,取整方向是一致的,故取模等价于取余
对任何一个小于0的数,对其进行0向取整和-∞取整,取整方向是相反的,故取模不等价于取余
- 结论:
两个同符号数据参与取余,取模等价于取余,不同语言余数相等
两个不符号数据参与取余,取模不等价于取余,余数大小需考虑语言取整规则