Bootstrap

详解 -- 计算机中取模运算和取余概念辨析

参考链接–百度百科

取模运算是求两个数相除的余数

  • 取模主要是用于计算机术语中。取余则更多是数学概念。
  • 取模运算(Modulo Operation)和取余运算(Remainder
    Operation)两个概念有重叠的部分但又不完全一致。
    主要的区别在于对负整数进行除法运算时操作不同

本文参考链接–阿里
知乎有个高赞的结论是错的,一定要懂得辨别啊老铁们!!!

1. 了解取整概念

计算机中取模还是取余主要是取整的不同

1.1 向 0 取整

C 语言中整数除法就是遵循这一取整方式。
下面代码中浮点数字面量拷贝赋值时发生了隐式类型转换,向 0 取整。

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

1.2 floor 取整(向下取整)

本质是向-∞取整,注意输出格式要不然看不到结果,比如:

#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;
}

1.3 ceil 取整

本质是向+∞取整,注意输出格式要不然看不到结果,比如:

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

1.4 round 取整

本质是四舍五入取整,比如:

#include <stdio.h>
#include <math.h>
int main()
{
    printf("%.1f\n", round(2.1));//结果是2
    printf("%.1f\n", round(2.9));//结果是3
    printf("%.1f\n", round(-2.1));//结果是-2
    printf("%.1f\n", round(-2.9));//结果是-3
    
    return 0;
}

2. 取模 / 余

1.1 定义

如果 a 和 d 是两个自然数,d 非零,可以证明存在两个唯一的整数 q 和 r
满足: 
	a = q*d + r 且 0 ≤ r < d。其中,q 被称为商,r 被称为余数

1.2 对正数取模/余

对a 和 d 都为正数时,取模和取余结果是一致的。
如下示例:

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; 
}

1.3 对负数取模/余

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 )	//r = -1 ,称为负余数
Python : - 10 =- 4* 3 + 2	//r = 2	,称为正余数

由上可知:具体余数 r 的大小,本质是取决于商 q 的取整规则:

  • 取余取整规则:尽可能让商,进行向 0 取整
  • 取模取整规则:尽可能让商,向 -∞ 方向取整

故 C 中 %, 本质其实是取余;Python中%,本质其实是取模。

1.4 总结

  • 由上这时就知道为什么正整数的取模和取余结果是一致,而对负数的取模和取余却不一致
    • 对任何两个同符号的两个实数,无论是对其进行取余的 向 0 取整,还是对其进行取模的 向 -∞ 取整,取整方向是一致的,故取模等价于取余

      • 例:
        对 -7 和 -3 进行取模/取余操作(c++ 和 java是取余,其余都是取模),结果都一致:
        C++(G++ 编译)cout << -7 % (-3);-1
        Java(1.6)System.out.println(-7 % (-3));-1
        Python 2.6-7 % (-3)-1
        百度计算器-7 mod (-3)-1
        Google 计算器-7 mod (-3)-1
    • 对任何符号不同的两个实数,对其进行取余时是向 0 取整,对其进行取模的 向 -∞ 取整,取整方向不一致,故取模不等价于取余

      • 例:
        对 -7 和 3 进行取模/取余操作:

        • (c++ 和 java)取余 商向 0 取整故:-7 = (-2) *3 - 1
        • (其他的)取模 商向 -∞ 取整故: -7 = (-3)* 3 + 2
        语言语句输出
        C++(G++ 编译)cout << (-7) % 3;-1
        Java(1.6)System.out.println((-7) % 3);-1
        Python 2.6(-7) % 32
        百度计算器(-7) mod 32
        Google 计算器(-7) mod 32
;