什么是取整?有几种取整方式?C语言又是哪种方式?取模取余一样吗?

article/2025/11/9 12:54:10

   大家都知道取整这回事,但是对于取整只有单一的认识,请看下面代码。

int main()
{int j = -2.9;int i = 2.9;printf("%d\n", j);printf("%d\n", i);return 0;
}

 看这串代码我们先不管数据溢出的问题,直接看最后的结果等于 什么

大家都知道最后结果会是-2.9变成-2,2.9变成2.

但是为什么会这样呢?我相信比较多人是不知道的

是因为一共有四种取整方式

第一种取整模式:向0取整

我们C语言默认是向0取整所以才等于这个结果

向0取整的意思是:只要你不是整数就把余数抹掉,变成整数。不是我们理解的四舍五入。

C语言里面有一个函数是和向0取整是一样作用,trunc函数。看代码

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>//使用trunc这个函数要调用这个库函数int main()
{int j = -2.9;int i = 2.9;printf("%d\n", (int)trunc(j));//因为trunc这个函数返回的是浮点数,所以要强转成intprintf("%d\n", (int)trunc(i));return 0;
}

 如图所示,是一摸一样的。

第二种取整模式:负无穷取整,floor取整

负无穷取整的意思是:只要是负数有余数就进一位,正数和向0取整一样

代码验证

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>//使用trunc这个函数要调用这个库函数int main()
{printf("%lf\n",floor(-2.1));printf("%lf\n",floor(-2.9));printf("%lf\n", floor(2.1));printf("%lf\n", floor(2.9));return 0;
}

 因为是负无穷取整-2.1和-2.9变成-3.0,正数2.1和2.9是向0取整的原则变成了2.0

第三种取整方式:向正无穷取整,ceil取整

正无穷取整模式:正数只要有余数就进1,负数和向0取整

代码验证

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>//使用trunc这个函数要调用这个库函数int main()
{printf("%lf\n",ceil(-2.1));printf("%lf\n",ceil(-2.9));printf("%lf\n",ceil(2.1));printf("%lf\n",ceil(2.9));return 0;
}

因为是正无穷取整2.1和2.9都有余数所以进1变成了3.0,-2.1和-2.9 一样是向0取整的原则等于2.0

第四种取整方式:四舍五入取整,round取整

四舍五入模式:就是我们数学进位用的那个

代码验证

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>//使用trunc这个函数要调用这个库函数int main()
{printf("%lf\n",round(-2.1));printf("%lf\n",round(-2.9));printf("%lf\n",round(2.1));printf("%lf\n",round(2.9));return 0;
}

四舍五入-2.1余数不是四以上所以等于-2.0,-2.9余数大于4所以进1等于-3.0,2.1和-2.1一样,2.9和-2.9一样 

四种取整方式的汇总代码

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>//使用trunc这个函数要调用这个库函数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;
}

 

 我们从图可以看见,有的取整方式不同但是最后取整结果有的是相同的

大家在这里可能就会想了,为什么要有那么多种取整方式。难道是和大小端一样?吃鸡蛋先吃大头还是小头一样?

其结果其实是各有各的用处,比如负无穷取整,像女孩子都希望自己年龄小点,女孩子实在要回答年龄的话,17岁9个月,都会回答成17岁。

像正无穷取整,有的年轻人有本事坐上了领导这个位置,怕年龄小,服不了底下员工,所以会把年龄取大点。

这些东西就不多聊了

我们来聊聊取模

为什么这里会等于1呢? 难道是10/3剩余1,所以等于1吗?

不对哦!!!取模和取余是有区别的哦

我们用取模简单公式来分析下结果

取模的基本概念

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

我们来带入一下公式,我们来求10%3的模

因为:a=10,d=3,q=3,r=1 0<=r<d(3)
所以:a = q*d+r -> 10=3*3+1

如果是这样呢?

那要是换成python呢?

 可以看到3.9.5版本的python出来的答案和C语言的答案是不一样的

结论:可以看到单单是知道取模的基本定义是不够用的

因为在C中,现在 - 10 % 3出现了负数,根据定义:满足 a = q * d + r 且0 ≤ r < d,C语言中的余数,是不满足定义的,
    因为,r < 0了。
    故,大家对取模有了一个修订版的定义:
    如果a和d是两个自然数,d非零,可以证明存在两个唯一的整数 q 和 r,满足 a = q * d + r, q 为整数,且0 ≤ | r |
    < | d | 。其中,q 被称为商,r 被称为余数。
    有了这个新的定义,那么C中或者Python中的“取模”,就都能解释了。
    解释C : -10 = (-3) * 3 + (-1)
    解释Python: - 10 = ( ? ) * 3 + 2, 其中,可以推到出来, '?'必须是 - 4(后面验证).即 - 10 =     ( - 4) * 3 + 2,才能
    满足定义。
    所以,在不同语言,同一个计算表达式,负数“取模”结果是不同的。我们可以称之为分别叫做正余数 和 负余数

如果是细心的朋友就发现了,我在发python的图片时,把除数给算了,算到-10/3等于-3.333大概这样的数,那么为什么又会等于-4呢?

那就要回到我们文章刚开始讲整数的四种取整模式了,而python的取整模式可以很明显的看到是负无穷取整,所以等于-4,故定义- 10 = ( -4) * 3 + 2,成立

那么回答一个前面的问题取模和取余一样吗?

答案是不一样的,虽然大部分不严格定义的时候是一样的,但是严格起来就完全不一样了

取余或者取模,都应该要算出商,然后才能得出余数。
本质 1 取整:
取余:尽可能让商,进行向0取整。
取模:尽可能让商,向 - ∞方向取整

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

那么大家还记得刚开始所有取模方式的那个表吗?有的取整方式不一样,但是在一定时候是相同的,正数向0取整和负无穷取整一样

总结:所以为什么我们在C语言当中没有发现这个问题,是因为我们在C语言取模中从来没有取过负数,都是取模取的是正数

文章写作不易:所以兄弟们,给xd赞和关注吧!谢谢了


http://chatgpt.dhexx.cn/article/Qmfk1oCt.shtml

相关文章

C语言学习之取整取余

1.前言 对于取整&#xff0c;在数学中我们最常见的作法就是四舍五入取整。而在C语言中&#xff0c;我们则是直接通过取整数部分&#xff0c;舍弃小数部分的方式进行取整。那么&#xff0c;所有语言的取整方式是相同的吗&#xff1f;而对于取余&#xff0c;我们可能经常会听到取…

C语言取整方法

文章目录 1. 直接赋值给整型变量int2. 整数除法运算&#xff08;“int / int”&#xff09;取整除法四舍五入 3. 使用floor函数4. 使用ceil函数5. 使用round函数 1. 直接赋值给整型变量int 作用&#xff1a; 使用该方法是将小数部分去除。 int i 3.5;或i (int)3.5; #include…

数据结构——浅谈链表

上午翻源码&#xff0c;翻到了原来学习数据结构时自己实现的链表源码&#xff0c;特此总结一下。源码可能有很多不完善的地方&#xff0c;请多谅解。 按照惯例&#xff0c;还是先来介绍下什么是链表。 链表是一种数据结构&#xff0c;在内存中通过节点记录内存地址而相互链接形…

数据结构:链表-C语言实现

文章目录 链表一. 前言二. 链表的定义2.1 概念2.2 分类 三. 单向无头不循环链表3.1 概念和说明3.2 定义链表结构体3.3 函数接口3.3.1 申请节点3.3.2 链表头插3.3.3 链表尾插3.3.4 在pos节点之后插入3.3.5 在pos节点之前插入3.3.6 链表头删3.3.7 链表尾删3.3.8 删去pos节点3.3.9…

数据结构——链表

数组是常用的数据结构&#xff0c;但是有其局限性&#xff1a; 编译期需要确定元素大小 数组在内存中是连续的&#xff0c;插入或者删除需要移动数组中其他数据 数组适合处理确定长度的&#xff0c;对于插入或者删除不敏感的数据。如果数据是频繁变化的&#xff0c;就需要选择…

数据结构-链表

链表 一、介绍1、单链表1、单链表结构体&#xff1a;2、单链表头插法&#xff1a;3、单链表尾插法&#xff1a; 二、例题1、双指针&#xff08;获取倒数第K个元素、获取中间位置的元素、判断链表是否存在环、判断环的长度、查找第一个公共节点、回文链表&#xff09;1、 判断链…

C语言数据结构、十字链表的分析及实现

目录 前言 一、什么是十字链表 二、认识十字链表 1.十字链表的组成 2.顶点和弧的连接 三、代码逻辑实现 1.出度 2.入度 总结 前言 无论是什么程序都要和数据打交道&#xff0c;一个好的程序员会选择更优的数据结构来更好的解决问题&#xff0c;因此数据结构的重要性不言…

JS 数据结构:链表

单链表 每个节点中只包含一个指针域的链表称为单链表。 头结点—其指针域指向表中第一个结点的指针&#xff08;头结点不是必须的&#xff0c;只是习惯上加上头结点&#xff0c;而头结点的数据域一般记录的是该链表的相关数据&#xff0c;如&#xff1a;链表长度&#xff09;…

数据结构中链表和列表的区别

顺序表和链表由于存储结构上的差异&#xff0c;导致它们具有不同的特点&#xff0c;适用于不同的场景。通过系统地学习顺序 表和链表我们知道&#xff0c;虽然它们同属于线性表&#xff0c;但数据的存储结构有本质的不同。 • 顺序表存储数据&#xff0c;需预先申请一整块足够…

数据结构(六)——循环链表

一、循序链表简介 1、循环链表的定义 循环链表的任意元素都有一个前驱和一个后继&#xff0c;所有数据元素在关系上构成逻辑上的环。 循环链表是一种特殊的单链表&#xff0c;尾结点的指针指向首结点的地址。 循环链表的逻辑关系图如下&#xff1a; 2、循环链表的设计实现 …

数据结构-使用链表实现栈

目录结构 Stack接口 package LinkedListStack;public interface Stack<E> {int getSize();boolean isEmpty();void push(E e); //向栈中添加元素E pop();//向栈中取出元素E peek();//查看栈顶的元素 }LinkedList类 package LinkedListStack;public class LinkedList<…

数据结构 | 链表的实现

目录 单链表双链表数组结构和链式结构的对比 线性表中&#xff0c;除了顺序表这一重要的结构&#xff0c;还有链式结构&#xff0c;而这也是我们常说的链表。 一般是通过定义结构体(类)的方式来表示链表的每一个结点。一般而言&#xff0c;链表的结点都会有数据域和地址域。数据…

Java数据结构之链表

目录 一.单链表 1.单链表的介绍和内存布局 2.单链表的添加和遍历 3.单链表的插入 4.单链表的删除 二.双向链表 1.添加节点 2.遍历节点 3.插入节点 4.删除结点 5.测试 三.单向环形链表 1.问题的引出 ​编辑 2.构建环形链表 1.创建结点 3.测试 3.约瑟夫问题代码的…

c++数据结构:链表

链表是一种物理存储单元上非连续、非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点&#xff08;链表中每一个元素称为结点&#xff09;组成&#xff0c;结点可以在运行时动态生成。每个结点包括两个部分&#xff1a;一个是…

java数据结构-链表详解

文章目录 1.数据结构-链表详解1.1单链表1.1.1单链表节点的尾部添加1.1.2单链表节点的自动排序添加1.1.3单链表节点的修改1.1.4单链表节点的删除 1.2单链表面试题1.2.1单链表的有效节点个数1.2.2单链表倒数第k个结点1.2.3单链表反转1.2.4单链表逆序打印 1.3双向链表1.3.1双向链表…

C语言数据结构链表(图文)

目录 一、链表的简单理解与引入 1.1 链表的引入 1.2 节点的理解 1.3 链表的分类 二、常用链表功能的实现 2.1 首先是节点的定义&#xff0c; 2.2 节点的创建 2.3 单链表的尾插 2.4 单链表的尾删 2.5 单链表的头插 2.6 链表的头删 2.7 单…

【数据结构】链表的学习总结

目录 1.链表的概念2.链表的结构1️⃣链表中单个结点的结构2️⃣链表的整体结构 3.链表的分类4.链表的实现1️⃣单向无头非循环2️⃣双向带头循环 1.链表的概念 链表&#xff0c;是一种物理存储结构上非连续、非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表 中的指针…

C++数据结构之链表(详解)

主要参考文章地址 01.链表基础知识 | 算法通关手册 (itcharge.cn)&#xff09; 本次内容是对链表的总结&#xff0c;可以看了上面的文章之后。 在看我下面的内容&#xff0c;做一个简短的复习&#xff0c;且本内容的代码均用C实现&#xff0c;而参考资料的代码则为python。 …

[数据结构]链表之单链表(详解)

文章目录 [数据结构]链表之单链表前言1.链表1.1链表的概念及结构1.2单链表与顺序表的区别与优缺点1.3八种链表类型、单向带头循环链表单向带头非循环链表单向不带头循环链表单向不带头非循环链表双向带头循环链表双向带头非循环链表双向不带头循环链表双向不带头非循环链表 2.单…

【数据结构与算法】详解什么是链表,并用代码手动实现一个链表结构

本系列文章【数据结构与算法】所有完整代码已上传 github&#xff0c;想要完整代码的小伙伴可以直接去那获取&#xff0c;可以的话欢迎点个Star哦~下面放上跳转链接 https://github.com/Lpyexplore/structureAndAlgorithm-JS 本文将来讲解一下一种常见的线性数据结构—链表&a…