【C语言】负数取模、取余

简介: 首先谈谈关于数学取整的问题

一. 关于“取整”

首先谈谈关于数学取整的问题


1. 向0取整

C中的除法和取整规则都是向0取整,即所有小数都向 0 的方向取整:


02c3515b840a44ea895a7b29524db2b9.png

示例:

#include <stdio.h>
int main()
{
  // C中的除法和取整规则都是向0取整
  int i = -2.9;
  int j = 2.9;
  printf("%d\n", i); // -2
  printf("%d\n", j); //  2
  return 0;
}


补充:C++11中有一个trunc(...)取整函数,作用就是向0取整


f9d3e63bd58a48e088741bb06816ab0f.png


2. 向负无穷取整

使用 floor(...)函数,使得所有小数都向负无穷方向取整:


20797e37e149490b9637bcbcc095f5ca.png

示例:


#include <stdio.h>
#include <math.h> //因为使用了floor函数,需要添加该头文件
int main()
{
  //本质是向-∞取整
  printf("%f\n", floor(-2.9)); //-3
  printf("%f\n", floor(-2.1)); //-3
  printf("%f\n", floor(2.9));  //2
  printf("%f\n", floor(2.1));  //2
  return 0;
}


3. 向正无穷取整

使用ceil(...)函数,使得所有小数都向正无穷方向取整:

e9f2980c05584ae896b05eded0b86441.png


示例:


#include <stdio.h>
#include <math.h>
int main()
{
  // 本质是向+∞取整
  printf("%f\n", ceil(-2.9)); //-2
  printf("%f\n", ceil(-2.1)); //-2
  printf("%f\n", ceil(2.9));  //3
  printf("%f\n", ceil(2.1));  //3
  return 0;
}


4. 四舍五入式的取整

使用round(...)函数,可以完成对小数四舍五入式的取整:

#include <stdio.h>
#include <math.h>
int main()
{
  //本质是四舍五入
  printf("%f\n", round(2.1)); // 2
  printf("%f\n", round(2.9)); // 3
  printf("%f\n", round(-2.1));// -2
  printf("%f\n", round(-2.9));// -3
  return 0;
}


二. 关于“取模”的本质

取模的定义如下:


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


下面我们对比不同语言下负数取模的结果:


5fa2a356da38495892067bb7f37089e4.png

可以看到,在不同语言中计算同一个表达式,负数“取模”结果是不同的。我们可以分别称之为叫做正余数 和 负余数。


由上面的例子可以看出,具体余数r的大小,本质是取决于商q的。

而商,又取决谁呢?取决于除法计算的时候,取整规则。


Python的取整规则是向负无穷方向取整,所以先计算出来商是 -4,然后才得到余数是2

fd4d3f2c1b04488991ea15c56fcf0a35.png


C语言的取整规则是向0取整,所以先计算出来商是 -3,然后才得到余数是1

5f944defcf3c4387bedcadb2799b7e94.png


三. 取余和取模的区别

经过上面的例子,我们已经知道了取模(余)的本质是要先计算出商是多少,而商的值取决于商的取整规则。


所以区余和取模的区别也体现在 商的取整规则 上:


取余:尽可能让商,进行向0取整

取模:尽可能让商,向-∞方向取整

所以:


C中%,本质其实是取余

Python中%,本质其实是取模

关于取模和取余的一个规律


同符号数据相除,得到的商,一定是正数,即大于0!


所以在对其商进行取整的时候,向0取整和向-∞方向取整的值都一样,这样子的话:取模的值 = 取余的值。


相关文章
|
6月前
|
C语言
C语言的详解操作符(2)之取余操作符
C语言的详解操作符(2)之取余操作符
|
5月前
|
架构师 NoSQL C语言
[深入浅出C语言]理解取整、取余和取模
推荐一个零声教育C/C++后台开发的免费公开课程,个人觉得老师讲得不错,分享给大家:C/C++后台开发高级架构师,内容包括Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,[立即学习]
99 2
【C语言】输入一个整数,输出该数二进制表示中1的个数,其中负数用补码表示
输入一个整数,输出该数二进制表示中1的个数,其中负数用补码表示
|
机器学习/深度学习 存储 C语言
c语言实现负数转补码
c语言实现负数转补码
458 0
|
C语言
C语言入门笔记:运算符及取余%的坑
C语言入门笔记:运算符及取余%的坑
122 0
|
C语言 Python
⭐️ C语言符号 ⭐️你真的懂取余\取模运算吗?!
本文主要讲解并真正理解取余\取模运算是怎样的!
⭐️ C语言符号 ⭐️你真的懂取余\取模运算吗?!
|
C语言
C语言: 输入一批正整数(以零或负数为结束标志),求其中的奇数和。要求定义和调用函数int even(int n)判断整数n的奇偶性,当为奇数时返回1,否则返回0。
C语言: 输入一批正整数(以零或负数为结束标志),求其中的奇数和。要求定义和调用函数int even(int n)判断整数n的奇偶性,当为奇数时返回1,否则返回0。
1416 0
C语言: 输入一批正整数(以零或负数为结束标志),求其中的奇数和。要求定义和调用函数int even(int n)判断整数n的奇偶性,当为奇数时返回1,否则返回0。
|
C语言
C语言入门——取余运算
C语言入门——取余运算
359 0
|
C语言 人工智能
C语言数组下标是负数
   1 #include 2 #include 3 using namespace std; 4 5 int main(int argc, char *argv[]) 6 { 7 int a[10]; 8 int i, j, k; 9 ...
828 0
|
C语言 BI 人工智能
C语言数组下标是负数
        编程时我们经常会遇到处理边界问题的情况,这时数组的下标可能是从负数开始的。通常的方法是将边界分离出来单独处理,但这样比较麻烦,程序读起来也比较费力。
1168 0