什么是取整?有几种取整方式?C语言又是哪种方式?取模取余一样吗?
大家都知道取整这回事,但是对于取整只有单一的认识,请看下面代码。
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赞和关注吧!谢谢了
什么是取整?有几种取整方式?C语言又是哪种方式?取模取余一样吗?相关推荐
- java中有哪几种访问修饰符_Java语言中有4种访问修饰符
转载:http://wuhaidong.iteye.com/blog/851754 Java语言中有4种访问修饰符 在Java语言中有4中访问修饰符:package(默认).private.publi ...
- C语言中四种取整方式、取余/取模的运算以及负数取模的问题
零向取整.负无穷向取整.正无穷向取整.四舍五入取整 如果将一个浮点数赋值给整形,只会保存整数位: 这种取整方式为零向取整,C语言默认采用的是这种方式 C语言中也有对应的零向取整函数: 同理还有一种函数 ...
- 递归法:从n个小球中取m个小球(不放回),共有多少种取法?
从n个小球中取m个小球(不放回),共有多少种取法? 利用假设法 设3个球A,B,C,任意取出2个,可分为取出的球中含A的部分和不含A的部分.即AB,AC为一组,BC为一组. 4个A,B,C,D里面取3 ...
- Oracle取某个时间点前后的整半小时的时间点
Oracle取某个时间点前后的整半小时的时间点: 需求简述:例如考勤计算中,我们是以0.5小时为单位去计算考勤时数,则需要对上班时间向后取整,下班时间向前取整 例如:上班时间:8:18,按8:30计算 ...
- 口袋中有红黄蓝白黑5种颜色的球若干个。每次从口袋中任意取
* * 输入描述:出三个球,问得到3中不通过颜色的球口袋中有红黄蓝白黑5种颜色的球若干个.每次从口袋中任意取的可能取法.(枚举) * 问题描述: * 程序输出: * 问题分析:略 * 算法设计:略 * ...
- java取余位运算_java学习--高效的除模取余运算(n-1)hash
没有测试过使用取余运算符和位运算符都做同一件事时的时间效率! 取余运算符% 如3除以2取余数 int a = a = a%; 结果为1 上面是传统的方式进行求余运算. 需要先将10进制转成2进制到内存 ...
- 取模(余)%运算详解
取模(余)%运算详解 1.JAVA中 对于整型数a,b来说,取模运算是: 1.求 整数商: c = a/b; 2.计算模: a%b = a - ...
- C语言的三种整型数据类型:int、short int和long int
int数据类型的位数为16位,short int数据类型的位数也是16位.而long int的位数为32位,可用来存储比较大的整数. short int 和 long int可以缩写为short 和 ...
- 如何理解:先减1后取反和先取反后加1得到的结果是一样的,故仍可采用取反加1的方法,即对于机器数为负数,则有[X]原=[[X]补]补。
对二进制数来说,先减1后取反和先取反后加1得到的结果是一样的,故仍可采用取反加1的方法,即对于机器数为负数,则有[X]原=[[X]补]补. 当然你也可以用先减1后取反的方法来求补码对应的原码. 对于求 ...
- 【STM32】位操作、按位与、按位或、按位异或、取反、左移、右移等基础 C 语言知识补充
文章目录 1 位操作 1.1 按位与 1.2 按位或 1.3 按位异或 1.4 取反 1.5 左移 1.6 右移 2 单片机中常用操作 2.1 不改变其他位时,对某几个位设定值 2.2 移位操作提高代 ...
最新文章
- 把计算机网络关闭啦怎么打开,我在笔记本电脑里的“打开或关闭系统图标”中关闭了“网络系统图标”,哪么怎样做才能打开...
- 失败在大学生活中的三种功能
- 华硕k555l拆光驱_2L大小的迷你电脑用起来有什么区别?华硕VC66
- 部署Tomcat服务时,解决Cannot invoke Tomcat Manager 异常
- R语言中的聚类的使用
- vue2.0中Ajax库(axios)
- WebBrowser 操作(从网上收集)
- 【Android】Theme.AppCompat.Light 问题
- 剑指offer之重建二叉树
- vector 不初始化时什么状态_练车时,教练为什么不给你开空调?
- 大型企业的特色服务【我身边的戴尔企业级解决方案】
- Kali Linux 网络扫描秘籍 第三章 端口扫描(三)
- Qt安装Windows调试器
- 邮政储蓄计算机笔试题,邮储总行计算机类笔试题
- ANSYS SPEOS VRXPERIENCE-基于物理特性的智能驾驶传感器高精度仿真
- Nodejs KOA服务搭建打包
- vue3+vite assets动态引入图片的几种方式,解决打包后图片路径错误不显示的问题
- 星际争霸游戏中的操作心得
- dp P1968 美元汇率 题解
- 网络编程之bind函数
热门文章
- 合同生效需要哪些要件
- 80c51单片机P3引脚的第二功能
- DAOS 系统内部介绍(一)—— 概述
- 新品发布季第二场,APT威胁挖掘机「NDR流量监测系统」正式亮相
- 昭阳 E43A 的笔记本电脑 开启或者关闭笔记本自带无线网卡
- 库存管理中常见的5大问题
- activiti使用mysql,启动报错。
- The Apache Tomcat Native library which allows optimal performance in production environments wasn
- 运筹学系列(一)纳什均衡与最大最小博弈
- ept技术_Intel虚拟化技术——EPT、VPID