广告
返回顶部
首页 > 资讯 > 后端开发 > Python >python中的除法,取整和求模
  • 526
分享到

python中的除法,取整和求模

除法python 2023-01-31 05:01:27 526人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

首先注明:如果没有特别说明,以下内容都是基于python 3.4的。 先说核心要点: 1. /是精确除法,//是向下取整除法,%是求模 2. %求模是基于向下取整除法规则的 3. 四舍五入取整round, 向零取整int, 向下和

首先注明:如果没有特别说明,以下内容都是基于python 3.4的。

先说核心要点:

1. /是精确除法,//是向下取整除法,%是求模
2. %求模是基于向下取整除法规则的
3. 四舍五入取整round, 向零取整int, 向下和向上取整函数math.floor, math.ceil
4. //和math.floor在CPython中的不同
5. /在python 2 中是向下取整运算
6. C中%是向零取整求模。

如果你对上面这几点都很熟悉,那么就不要浪费时间往下看了,珍惜生命,远离泛滥的灌水文章

大纲如下:
1. 一个测试程序和它的输出
2. 取整和求模运算规则
3. python中其他的取整运算
4. //和math.floor在CPython中的不同
5. 运算符/在python 2 和python 3 中的区别
6. 其他讨论(求余和求模)

下面按顺序介绍:

1. 一个测试程序和它的输出
测试程序如下(python 3.4):

print('usage of 3 operators /, // and % in python 3.4')
print('1). usage of /')
print ('10/4 = ', 10/4)
print ('-10/4 = ', -10/4)
print ('10/-4 = ', 10/-4)
print ('-10/-4 = ', -10/-4)

print('\n2). usage of //')
print ('10//4 = ', 10//4)
print ('-10//4 = ', -10//4)
print ('10//-4 = ', 10//-4)
print ('-10//-4 = ', -10//-4)

print('\n3). usage of %')
print ('10%4 = ', 10%4)
print ('-10%4 = ', -10%4)
print ('10%-4 = ', 10%-4)
print ('-10%-4 = ', -10%-4)

输出结果如下:

usage of 3 operators /, // and % in python 3.4
1). usage of /
10/4 =  2.5
-10/4 =  -2.5
10/-4 =  -2.5
-10/-4 =  2.5

2). usage of //
10//4 =  2
-10//4 =  -3
10//-4 =  -3
-10//-4 =  2

3). usage of %
10%4 =  2
-10%4 =  2
10%-4 =  -2
-10%-4 =  -2

如果被除数和除数都是正整数,比如10对4求模,一般人都能算出来是2,但是如果两个或其中一个是负数,比如-10对4求模,取整除法和模应该如何计算呢?虽然我们可以从上面的输出总结一个现象律:模和除数同号(除非能整除是模是0),但是如何理解这个现象律呢,它的内在本质是什么呢?这是这篇文章主要讨论的问题。

2.取整和求模运算规则

求模运算规则是由除法规则定的,因为被除数(dividend), 除数(divisor),商(quotient)和模(或余数,modulus or remainder)在数学上必须满足如下关系:
被除数=除数*商+模 (方程1)
变化一下,已知被除数和余数,模可以通过商计算出来,计算公式如下:
模=被除数-除数*商 (方程2)

从wiki(https://en.wikipedia.org/wiki/Modulo_operation)查到三种不同的算法,这里拷贝了其中的一张图(只有英文版)

这里写图片描述
图1:三种不同的算法 。图中红线表示商,绿线表示模。横坐标表示被除数,纵坐标表示商或模。

这幅图可以分成三行两列,共6个子图。三行trancated/floored/Euclidean division代表三种取整除法(下面会讨论);两列的解释是:第一列positive divisor, 也就是说除数是正数,第二列negative divisor,除数是负数。那这幅图到底是什么意思呢? 现在拿第二行第一列的子图解释一下 (floored division, positive divisor),这里的横坐标表示被除数,纵坐标表示商或模。这个子图中除数(divisor)是正数,当被除数也是正数时(比如前面讨论的10对4求模),商和余数都是正数或零;当被除数是负数的时候(比如之前讨论的-10对4求模),采取了向下(负数方向)取整(rounded downwards, , 函数floor的功能),本来精确除法下答案是 (-10/4 = )-2.5,现在向下取整答案是(-10//4 =) -3,也就是取整后的结果(-3)必须小于等于精确结果(-2.5), 这时用商和模的关系(方程2)很容易计算出模是2, 这也是前面例子中讨论的。这就是python采用的floored division算法,这个算法可以说是python的//和%运算符采用的最重要也是唯一的规则(当然还有abs(模) < abs(除数)),对所有的情况都适用(你可以仔细看看开始讨论的测试程序和图1中第二行的两个子图)。其它的现象都可以从这个规则中推导出来。比如我们前面说的python模运算符%的一个现象规律:模要么与除数同号,要么是零(能整除的情况下)。其本质是由python采取的向下取整算法决定的。我们只需要记住python的取整规则是:向下取整!向下取整!向下取整!

另外两种:第一种truncated division,是向零取整,也就是简单粗暴地去掉小数部分,C语言采用这种方法(例子见后面的讨论)。还有一种是Euclidean division, 这里不讨论了,有兴趣的同学可以问度娘或谷哥。

当然还有一种取整法,就是我们耳熟能详的四舍五入法,:)。

下面接着介绍python中其它的取整方法。

3.python中其他的取整运算

首先说明,取整或模运算(比如a//b, a%b)中, a和b都可以是非整数,比如
-10.6//2.1=-6.0
-10.6//2.1=2.00000…

这也可以归纳到上面所说的向下取整规则中,当然还有一条隐蔽规则:模的绝对值小于除数的绝对值,也就是abs(模) < abs(除数)

python能够实现基本的四种取整运算:四舍五入,向零取整,向下取整和向上取整

四舍五入取整函数round

>>>round(3.5)
4
>>>round(-3.5)
-4
>>>round(3.49)
3
>>>round(-3.49)
-3

向零取整函数int

>>>int(3.99)
3
>>>int (-3.99)
-3

math模块中向下取整函数floor和向上取整函数ceil

>>>from math import floor, ceil
>>>floor(3.99)
3
>>>floor(-3.-1)
-4
>>>ceil(3.01)
4
>>>ceil(-3.99)
-3

4.//和math.floor在CPython中的不同

从以上讨论中可以看出,//和math.floor对除法运算都是向下取整,结果应该相同,比如

>>>from math import floor
>>>3//5 == floor(3/5)
True

但是

>>>1//0.05 == floor(1/0.05)
False

What? 不是说好的相同吗,友谊的小船怎么说翻就翻呢?

分开测试:

>>> 1/0.05
20.0
>>> 1//0.05
19.0
>>> floor(1/0.05)
20

先说结论:这个问题是由于cpython的向下取整除法运算符(//)的实现不是 浮点除法+floor 来实现而是用了(被除数 - 余数)/除数 导致的。
PS:Jython下可以得到20.0,而PEP里规定了a // b应该等于round(a/b),所以似乎这是cpython实现的一个bug?

首先先分析下1 / 0.05究竟应该等于多少。答案就是精确的20.0。简单解释下:IEEE754浮点数规定,如果一个浮点数的值不能被精确记录,那么它的值会被记成与这个数距离最近的可以被IEEE浮点数表示的数。首先,0.05在二进制下是无限循环小数,自然不能被精确记录,因此0.05这个浮点数的实际值是不等于0.05的,实际值是约为0.05 + 2.7e-18。之后做浮点除法,实际上做的是1 / (0.05+2.7…e-18),这个除法的结果大约是20 - 1.1e-15。这个值也不能被精确表示,恰好离这个数最近的可以表示的值就是20.0,因此即使有浮点数误差结果也是精确的20.0。既然1/0.05就是20.0,那么对他做floor运算自然也是20了。

现在的问题就是为什么1 // 0.05会变成19.0,要解决这个问题只能翻源码看//运算符的实现。
这里不贴源码了,结论是:cpython中x // y的实现实际上是round((x - fmod(x, y)) / y) ,其中fmod函数是求两个浮点数相除的余数。

这样一来就解释的通了:在十进制下,显然1除以0.05的余数应该是0.0。然而在IEEE浮点数环境中,0.05的实际值是约0.05 + 2.7e-18,略大于0.05,这样一来1除以这个数的余数就成了约0.05 - 5e-17,从1中减掉这么多之后就只剩0.95了,除以0.05再round后变成19.0。

注:这段主要参考知乎上的一篇文章(Http://www.zhihu.com/question/41017093/answer/89848433),如有兴趣,大家可查看,里面有源码。

5.运算符/在python 2 和python 3 中的区别

//和%运算符在2和3版本中一样,但是运算符/不一样,最开始的测试程序中和运算符/有关的部分在python 2.7中的输出结果是这样的:

print ('10/4 = ', 10/4)
print ('-10/4 = ', -10/4)
print ('10/-4 = ', 10/-4)
print ('-10/-4 = ', -10/-4)('1

输出:
('10/4 = ', 2)
('-10/4 = ', -3)
('10/-4 = ', -3)
('-10/-4 = ', 2)

除了大家熟知的print用法不一样外,这里要说的是运算符/在python 3以前的版本是向下取整(等同于//),这是大家要注意的。

6.其他讨论(求余和求模)
一篇文章(http://blog.sina.com.cn/s/blog_a3052b4a01018fd7.html)讨论求余和求模的区别 , 原文中列了一个表格,我拷贝在下面
这里写图片描述
原作者认为: 取模运算时,向0 方向舍入(fix()函数); 求余运算时,向无穷小方向舍入(floor()函数)。

还有一篇文章(http://www.cnblogs.com/xfzhang/arcHive/2010/11/25/1887214.html),讨论在matlab中取模(mod)与取余(rem)的不同。

不能说这些观点本身有什么错误,matlab 也确实给出了两个不同的函数,细化了区别。但我却认为这样处理把问题复杂化了,我们没有必要在文字上钻牛角尖,非得人为区分“求余”和”求模”。我们就可以简单地认为两者相同,比如统一用”求模” 表示(当然你也可以用“求余”),只是在数学运算和不同编程语言中求模时存在不同的取整算法,主要是上面讨论的三种:truncated division, floored division, Euclidean division。 C语言用的是truncated division, 而python用的是floored division.

--结束END--

本文标题: python中的除法,取整和求模

本文链接: https://www.lsjlt.com/news/188136.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • python中的除法,取整和求模
    首先注明:如果没有特别说明,以下内容都是基于python 3.4的。 先说核心要点: 1. /是精确除法,//是向下取整除法,%是求模 2. %求模是基于向下取整除法规则的 3. 四舍五入取整round, 向零取整int, 向下和...
    99+
    2023-01-31
    除法 python
  • Java和Python中的整除和求余运算
    执行如下的Java语句: System.out.println("5 / 3 = " + (5 / 3)); System.out.println("5 / -3 = " + (5 / -3)); System.out.println("...
    99+
    2023-01-31
    Java Python
  • Python中负数的除法和取模运算(和C
    一、除法: 除法的取整分为三类:向上取整、向下取整、向零取整。 1. 向上取整:向+∞方向取最接近精确值的整数。在这种取整方式下,5 / 3 = 2, -5 / -3 = 2, -5 / 3 =-1, 5 / -3 = -1 2. 向...
    99+
    2023-01-31
    除法 负数 Python
  • Python3除法中真除法、截断除法和下取整对比的实例分析
    这篇文章给大家介绍Python3除法中真除法、截断除法和下取整对比的实例分析,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Python3除法之真除法、截断除法和下取整对比有伙伴留言想看关于Python3中不同种除法取整...
    99+
    2023-06-02
  • python中取整数的几种方法
    目录1、向下取整: int()2、向上取整:ceil()3、四舍五入:round()4、分别取 1、向下取整: int() >>> a = 14.38 >...
    99+
    2022-11-12
  • Python中取整的几种方法小结
    前言 对每位程序员来说,在编程过程中数据处理是不可避免的,很多时候都需要根据需求把获取到的数据进行处理,取整则是最基本的数据处理。取整的方式则包括向下取整、四舍五入、向上取整等等。下面就来看看在Python...
    99+
    2022-06-04
    小结 中取 几种方法
  • Python中求取数字位数的方法
    Python中求取数字位数的方法 在Python中,我们经常需要计算一个数字的位数。例如,我们可能需要判断一个整数有多少位,或者需要将一个数字拆分成各个位的值。本文将介绍几种常见的方法来实现这个目标。...
    99+
    2023-10-24
    python 开发语言 Python
  • 在python中sum求和的方法
    这篇文章给大家分享的是有关在python中sum求和的方法的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。在python中sum求和的方法:使用sum语法求和【sum(iterable[, start])】,其中i...
    99+
    2023-06-07
  • Python中的FTP通信模块ftplib的用法整理
    Python中默认安装的ftplib模块定义了FTP类,其中函数有限,可用来实现简单的ftp客户端,用于上传或下载文件. FTP的工作流程及基本操作可参考协议RFC959. ftp登陆连接 from ...
    99+
    2022-06-04
    模块 通信 Python
  • Python浮点数乘法和整形乘除法的效率实例分析
    今天小编给大家分享一下Python浮点数乘法和整形乘除法的效率实例分析的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。问题:如...
    99+
    2023-06-30
  • Python中的模块导入和读取键盘输入的方法
    导入模块 import 语句 想使用Python源文件,只需在另一个源文件里执行import语句,语法如下: import module1[, module2[,... moduleN] 当解释器...
    99+
    2022-06-04
    模块 键盘输入 方法
  • Python中获取两数相除的商和余数
    方法一:可以使用//求取两数相除的商、%求取两数相除的余数。[/在Python中获取的是相除的结果,一般为浮点数] 方法二:使用divmod()函数,获取商和余数组成的元祖 实例代码: #!/usr/bin/python3 #...
    99+
    2023-01-31
    余数 Python 两数相
  • Python中的列表条件求和方法
    目录列表条件求和方法利用列表求和函数(可接收无数个参数求和)列表条件求和方法 list_data=[ [1.0, '配件', '522422', '铝扣板用纽扣', '金色', '...
    99+
    2022-11-11
  • Python浮点数取整、格式化和NaN处理的操作方法
    目录1. 取整的三种方法1.1 强转int类型1.2 采用math.ceil和math.floor1.3 采用round2. 格式化浮点数输出3. 执行精确的小数计算4. 无穷大、负...
    99+
    2022-11-11
  • Python DateTime的模块如何在相关类方法中的整理
    Python DateTime的模块如何在相关类方法中的整理,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。相关联的模块还有time与calendar 其中的time我们上面已经...
    99+
    2023-06-17
  • python中求和函数sum()的用法示例
    这篇文章给大家分享的是有关python中求和函数sum()的用法示例的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。python是什么意思Python是一种跨平台的、具有解释性、编译性、互动性和面向对象的脚本语言,...
    99+
    2023-06-14
  • python中TensorFlow神经网络模型的保存和读取方法是什么
    本篇内容主要讲解“python中TensorFlow神经网络模型的保存和读取方法是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“python中TensorFlow神经网络模型的保存和读取方法...
    99+
    2023-06-25
  • python辗转相除法求最大公约数和最小公倍数的实现
    目录辗转相除法求最大公约数和最小公倍数辗转相除法数学原理python代码实现用递归的方式实现Python3 20.辗转相除法算法分析源代码结果截图辗转相除法求最大公约数和最小公倍数 ...
    99+
    2022-11-11
  • Python中time模块和datetime模块的用法示例
    time模块方法: time.time():获取当前时间的时间戳 time.localtime():接受一个时间戳,并把它转化为一个当前时间的元组。不给参数的话就会默认将time.time()作为参数传入 ...
    99+
    2022-06-04
    模块 示例 Python
  • 实例讲解Python中SocketServer模块处理网络请求的用法
    SocketServer创建一个网络服务框架。它定义了类来处理TCP,UDP, UNIX streams 和UNIX datagrams上的同步网络请求。 一、Server Types 有五个不同的服务器类...
    99+
    2022-06-04
    实例 模块 网络
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作