本系列文章译自Python之父 Guido van Rossum 的系列博客“The History of Python”。这个博客系列对我们理解Python及其演变很有帮助,经Guido同意,在这里翻译推荐给大家,希望大家喜欢,也请大家多多指教!
系列地址:http://blog.kantli.com/theme/1

1

今天又有人问我,为什么 Python 中整数相除是向下取整,而不像 C语言一样靠 0 取整?

对正整数来说,两种取整方式的结果是一样的:

>>> 5//2
2

如果其中一个是负数,结果就不是向零靠近了(而向负无穷靠近):

>>> -5/2
-3
>>> 5//-2
-3

这个问题让一些人感到困扰,但其实是有数学考虑的。整除操作(//)与取模操作(%)是一个组合,共同实现一个数学关系(所有变量都是整数)

# a/b = q 余 r

# b*q + r = a,其中 0 <= r < b

当 a 为负数(b 保持正数),我们有两个选择:一个是让 q 向零取整,于是余数 r 会变成负数,即 0 <= abs(r) < b;另一个是让 q 向负无穷取整,则余数的设定保持不变。

数学家们总是倾向于后一种选择。(参考维基百科https://zh.wikipedia.org/wiki/%E6%A8%A1%E9%99%A4)

而在 Python 中,我也选择了后一种方案,因为在实际应用中,存在一些 a 既可能为正数也可能为负数的情况。

以 POSIX 时间戳(1970年以来的秒数)为例,如果我们要获取当前的具体时间,由于每天为 24 * 3600 = 86400 秒,只需直接取模 t % 86400 就可以了。假如时间戳为负数,即在 1970 年之前,那么,为获得正确结果,就只能用向下取整,而不是向零取整。

我能想到的另一个例子是图像点位的计算。而且我很确定,还有许多其它例子。

顺便提一下,如果 b 取负数,整个等式就反过来了:0 >= r > b。


2

那么,C语言为什么采用了向零取整呢?或许是因为当时的硬件设计——在最早期的硬件中,负数的表现方式是“符号 + 数字”,而不是现在一般采用的补码(至少整数是如此)。

我用的第一台电脑是一台 CDC 主机,其整数和浮点数都是用补码表示的,60 个 1 表示的是负 0。

Tim Peters 曾担心我会把这个原则扩展到浮点数。他或许是对的,当 x 是一个非常小的负数时,向下取整原则会导致 x % 1.0 出现精度损失。但这个问题并不影响我让整数采取向下取整原则。


PS. 请注意,我用的符号是 // 而不是 /,这是 Python 3 中的句法,在 Python 2 中也可以使用,表示用户明确使用整除而不是除号。Python 2 中的 / 操作可能会有歧义,因为当两个参数都是整数时,它只返回整数,而当存在浮点数参数时,则返回浮点数。不过这是另一个故事了,可以参考 PEP 238。

公众号:ReadingPython

c++语言取整为什么要加0.5_22. 为什么 Python 中的整除是向下取整?相关推荐

  1. 向下取整符号_22. 为什么 Python 中的整除是向下取整?

    本系列文章译自Python之父 Guido van Rossum 的系列博客"The History of Python".这个博客系列对我们理解Python及其演变很有帮助,经G ...

  2. python整数转换字符串_使用Python中的str()函数将整数值转换为字符串

    python整数转换字符串 Given an integer value and we have to convert the value to the string using str() func ...

  3. c++语言取整为什么要加0.5_C/C++之取整函数

    C/C++之取整函数 后面的double x放的是你的浮点型参数. 取整函数向上取整和向下取整有现成的函数.不过它们的缺点是正数和负数用到的函数是相反的容易混淆. 函数名函数说明------>右 ...

  4. python中int() 按照“四舍五入”的方式取整

    使用 int() 将小数转换为整数,小数取整会采用比较暴力的截断方式,即向下取整. (注:5.5向上取整为6,向下取整为5) 正常情况下 int(5.5) 结果为5 如果想要让其按照人类的思维&quo ...

  5. c语言 连通域算法 递归,VC++ 6.0编写计算机图形学中的种子填充算法,想用递归的八向连通域,求助!...

    VC++ 6.0编写计算机图形学中的种子填充算法,想用递归的八向连通域,求助!0 填充函数代码如下: void CComputerGraphicsView::PolygonFill2()//区域填充函 ...

  6. python是什么语言、即变量不需要显示声明数据类型-python中可以声明变量类型吗...

    变量(variable)是Python语言中一个非常重要的概念.变量的主要作用就是为Python程序中的某个值起一个名字.类似于"张三"."李四"." ...

  7. python中布尔型的值_在python中对于bool布尔值的取反操作

    背景 根据公司业务的需求,需要做一个对于mysql数据库的大批量更新.脚本嘛也是干干单单.使用了redis的队列做缓存,可以异步并发的多任务进行更新. 有点难受的地方在于,请求访问时,因为一些网速,速 ...

  8. python取反操作_在python中对于bool布尔值的取反操作

    背景 根据公司业务的需求,需要做一个对于mysql数据库的大批量更新.脚本嘛也是干干单单.使用了redis的队列做缓存,可以异步并发的多任务进行更新. 有点难受的地方在于,请求访问时,因为一些网速,速 ...

  9. python中字体加粗_全网python中xticks字体加粗搜索-第二电脑网

    第二电脑网 网页 电脑论坛 电脑知识 搜吧 问问 博客 新闻 更多» soso.mark('logo_start'); soso.mark('logo_end'); 帮助 | 第二电脑网为主页 | 提 ...

  10. python快速加引号_在python中如何快速地将一串字符串首尾加上双引号?

    python初学者.现在想做一个打包的小任务.目标地址为: D:\py_backup_test\iu d 然后将这个地址放在target_dir 里,并加上当前时间和后缀名: import os im ...

最新文章

  1. ScheduledThreadPoolExecutor定时任务线程池执行原理分析
  2. 【论文投稿】计算机学科部分核心期刊投稿攻略
  3. Oracle入门(十四.12)之游标FOR循环
  4. 将深度缓冲z值变换到相机坐标系
  5. 情人节来了,教你个用 Python 表白的技巧
  6. python处理excel的优势-用Python读写Excel文件的方式比较
  7. Cmake构建_设置debug与release不同名字
  8. C#利用扩展方法,不引入新的类型,实现矩阵的操作
  9. 安装多个 PHP 版本(PHP7, PHP5)
  10. ZenTaoPMS.11.6.5.zbox_64.tar
  11. 零中频接收机频率转换图_相干光接收机的相关问题
  12. Max 文件制作三维场景
  13. DB2 SQL消息查询
  14. java使用poi操作ppt(导入,导出,读取,添加,拼接,替换文本,页面排序)
  15. BUUCTF Web 极客大挑战 2019 EasySQL
  16. arduino编码器计数_基于Arduino开发环境的光电编码器检测仪设计方案 - 全文
  17. Oracle 中的 ST_Geometry
  18. 新型多功能、高性能量子点,可以用于医学成像、量子计算
  19. hive正则匹配:regexp_replace、regexp_extract、regexp
  20. 427. 建立四叉树

热门文章

  1. Ubuntu pycharm配置conda已安装好的环境,以及conda激活环境的命令相关操作
  2. 黑马程序员 (重要)单进程、线程、非堵塞实现并发的原理
  3. python SQLite 初识
  4. opencv打开双目
  5. Atitit 并发处理 go与 java对比较 目录 1. 并发编程的七个模型 线程,fp,actor,csp 数据级并行 Lambda 1 2. 四种并发编程模型简介 多线程,callback
  6. Atitit ftp概念与ftpclient 目录 1. Concept 1 1.1. Tftp(simple ftp) sftp ssh port22 1 1.2. ftp server
  7. atitit 部门日常工作流程体系 日常日程表 日常工作内容列表清单.docx
  8. Atitit 贝叶斯算法的原理以及垃圾邮件分类的原理
  9. paip.uapi 获取网络url内容html 的方法java php ahk c++ python总结.
  10. 恒生电子:金融IT的“高铁模式”,如何从引进到领先?