为什么在 Python 中 math.floor(x/y) != x // y 表示两个可整除的浮点数?

2023-12-24

我一直在阅读有关Python中的除法和整数除法以及Python2与Python3中的除法之间的差异。在大多数情况下,这一切都是有道理的。 Python 2 仅当两个值都是整数时才使用整数除法。 Python 3 始终执行真除法。 Python 2.2+ 引入了//整数除法运算符。

其他程序员提供的示例很好,很简洁,例如:

>>> 1.0 // 2.0      # floors result, returns float
0.0
>>> -1 // 2         # negatives are still floored
-1

How is //实施的?为什么会出现以下情况:

>>> import math
>>> x = 0.5 
>>> y = 0.1
>>> x / y
5.0
>>> math.floor(x/y)
5.0
>>> x // y
4.0

不应该x // y = math.floor(x/y)?这些结果是在 python2.7 上生成的,但由于 x 和 y 都是浮点数,因此结果在 python3+ 上应该是相同的。如果存在一些浮点错误,其中x/y实际上是4.999999999999999 and math.floor(4.999999999999999) == 4.0这不会反映在x/y?

但以下类似情况不受影响:

>>> (.5*10) // (.1*10)
5.0
>>> .1 // .1
1.0

我没有发现其他答案令人满意。当然,.1没有有限的二进制展开式,所以我们的预感是表示错误是罪魁祸首。但这种预感本身并不能真正解释原因math.floor(.5/.1) yields 5.0 while .5 // .1 yields 4.0.

重点是a // b is actually doing floor((a - (a % b))/b),而不是简单地floor(a/b).

.5 / .1 是exactly 5.0

首先,请注意,结果.5 / .1 is exactly 5.0在Python中。情况确实如此,尽管.1无法准确表示。以这段代码为例:

from decimal import Decimal

num = Decimal(.5)
den = Decimal(.1)
res = Decimal(.5/.1)

print('num: ', num)
print('den: ', den)
print('res: ', res)

以及相应的输出:

num:  0.5
den:  0.1000000000000000055511151231257827021181583404541015625
res:  5

这表明.5可以用有限二进制展开来表示,但是.1不能。但这也表明,尽管如此,结果.5 / .1 is确切地5.0。这是因为浮点除法会导致精度损失,并且损失的量den不同于.1就在这个过程中丢失了。

这就是为什么math.floor(.5 / .1)正如您所期望的那样工作:因为.5 / .1 is 5.0, 写作math.floor(.5 / .1)和写作一样math.floor(5.0).

那么为什么不呢.5 // .1结果是5?

人们可能会认为.5 // .1是简写floor(.5 / .1), 但这种情况并非如此。事实证明,语义不同。这即使是PEP says https://www.python.org/dev/peps/pep-0238/:

楼层除法将在所有Python数值中实现 类型,并且将具有以下语义

    a // b == floor(a/b)

事实证明,语义.5 // .1 are actually相当于:

floor((.5 - mod(.5, .1)) / .1)

where mod是浮点余数.5 / .1四舍五入到零。通过阅读以下内容可以清楚地了解这一点Python源代码 https://github.com/python/cpython/blob/829b49cbd2e4b1d573470da79ca844b730120f3d/Objects/floatobject.c#L578.

This事实是.1无法用二进制展开来精确表示会导致问题。的浮点余数.5 / .1 is not zero:

>>> .5 % .1
0.09999999999999998

事实并非如此,这是有道理的。由于二进制展开.1比实际的小数稍大一些.1, 最大整数alpha这样alpha * .1 <= .5(在我们的有限精度数学中)是alpha = 4. So mod(.5, .1)是非零的,并且大约是.1. Hence floor((.5 - mod(.5, .1)) / .1)变成floor((.5 - .1) / .1)变成floor(.4 / .1)这等于4.

这就是为什么.5 // .1 == 4.

为什么//去做?

的行为a // b可能看起来很奇怪,但它与math.floor(a/b)。在他的blog http://python-history.blogspot.com/2010/08/why-pythons-integer-division-floors.html关于 Python 的历史,Guido 写道:

整数除法运算 (//) 及其兄弟,取模 运算(%),一起满足一个很好的数学 关系(所有变量均为整数):

a/b = q with remainder r

这样

b*q + r = a and 0 <= r < b

(假设 a 和 b >= 0)。

现在,Guido 假设所有变量都是整数,但是如果a and b是浮标,if q = a // b. If q = math.floor(a/b)关系won't一般情况下持有。所以//可能是首选,因为它满足这种良好的数学关系。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么在 Python 中 math.floor(x/y) != x // y 表示两个可整除的浮点数? 的相关文章

随机推荐

  • 代码从 Python 2.6 更改为 3.x

    我想得到pywbem http pywbem svn sourceforge net 在 Python 3 2 中工作 在 2 6 中工作正常 但在 mof compiler py 中的这部分代码上构建失败 File pywbem 0 7
  • Postgresql 获取一列或大表中一组唯一值的最快方法

    我在 Postgresql 数据库中有一个不断增长的 可能非常大的表 其中包含来自不同 设备 的不同 通道 的 数据 例如 Table data id PK device id FK gt device channel id FK gt c
  • 迁移出 AppEngine

    我有一个在 AppEngine 上运行的应用程序 每天使用大约 50 个 CPU 小时 大部分时间都花在等待数据存储上 我正在考虑将其从 AppEngine 移至 Rackspace 云服务器之类的地方 因为我认为如果我可以将部分工作卸载到
  • iOS - 如何检查模式视图是否存在

    有没有办法检查模式视图是否存在 我想仅在存在模式视图时运行方法 另外 如果我有多个模态视图 有没有办法检查是否存在某个模态视图 我使用以下代码来呈现和关闭模态视图 self presentModalViewController myModa
  • 如何从 QML 访问 C++ 枚举?

    class StyleClass public QObject public typedef enum STYLE RADIAL STYLE ENVELOPE STYLE FILLED Style Style m style h文件中有上述
  • 如何在 PHP 5.2.8 中比较两个 DateTime 对象?

    看了一下PHP文档 有以下两种方法DateTime对象似乎都可以解决我的问题 日期时间 差异 http au php net manual en datetime diff php 获取差异并使用它来确定哪个更古老 日期时间 获取时间戳 h
  • 用于导航到变量类的 Visual Studio 快捷方式

    Usually it is a simply as clicking on F12 on the declaration class type of a variable 然而 随着使用量的增加var关键字 我想知道 Visual Stud
  • 错误:为 h5py 构建轮子失败无法构建 h5py 错误:无法为 h5py 构建轮子,这是安装 pyproject.toml-basedprojects 所必需的

    当我运行以下命令来安装tensorflow时 出现此错误 python3 m pip install tensorflow macos ERROR Failed building wheel for h5py Failed to build
  • 小胡子模板不会在表 tbody 内呈现

    为什么相同的 JSON 对象代码会生成输出ul元素 但不带有table tag 我的小胡子模板如下 div h3 name h3 ul students li name age li students ul div div table th
  • PHP 在路径中包含变量

    因此 我们构建的网站必须从本地开发服务器移植到测试服务器 然后移植到实时服务器 为此我们创建了一个变量 当我们将网站从服务器移动到下一个服务器时 想法是简单地更改 path 定义以适应新的开发服务器 目前 当我们调用包含时 我们在每个页面上
  • 在 CSS 中使用相对大小而不是固定大小

    我想使用相对大小而不是固定大小 我想用它们 我的CSS是 body font 10px wrap font 1 2em wrap ul li padding left 2em 的价值是什么li的内边距以 px 为单位 我猜它是 2 0 10
  • Java Transformer 如何忽略名称空间

    我必须将 XML 转换为 XHTML 但 XML 定义了命名空间xmlns http www lotus com dxl 它从未在整个 XML 中使用过 因此解析器不会解析任何内容 有没有办法忽略命名空间 我正在使用 Oracle java
  • 使用 Web Api 验证 .NET MVC 应用程序

    我有一个基于 SPA VS 2013 模板的 Web Api 2 项目 我在该 Api 中配置了不记名令牌身份验证 我还有一个单独的 MVC 5 项目 我想使用该 Web Api 进行身份验证 那可能吗 如何 到目前为止我做了什么 在我的
  • Eclipse 中没有服务器;尝试安装 Tomcat

    我正在尝试在 Eclipse 中安装 Tomcat 但无法显示服务器选项卡 当我去窗口 gt 显示视图 gt 其他并输入 服务器 我没有得到任何结果 当我去文件 gt 新建 gt 其他并输入 服务器 我也什么也得不到 有谁知道我的服务器出了
  • 如何使用java api知道jenkins构建执行器是否空闲

    我想通过使用 java jenkins API 知道 jenkins 中的构建执行器是否空闲 空闲或任何作业正在主节点中运行 而我的要求是这样的 如果任何执行者有空 我必须触发詹金斯工作 否则我会等到他们可用 为此我必须使用 Jenkins
  • 使用nextjs和react-jss时className不匹配

    我将 nextjs 与 typescript 和 React jss 一起使用 我收到错误 Warning Prop className did not match Server mobileNavToggle 0 2 10 Client
  • 从客户端控制器指定 Mongo 查询参数 (MEAN.JS)

    我正在使用 MongoDB Angular Express 和 Node MEAN 堆栈 构建一个应用程序 我使用 MEAN JS 生成器来构建我的应用程序 我将使用文章模块作为参考 假设我的文章集合中有 7000 条记录 并且每条记录都有
  • 如何在 Android 中使用新的 Dialogflow SDK V2

    我对迁移到 Dialogflow V2 有点困惑 我有一个 Android 应用程序使用https github com dialogflow dialogflow android client https github com dialo
  • 交互式地处理占用大量内存的列表对象

    我最近发现了包裹的奇妙之处bigmemory ff and filehash处理非常大的矩阵 如何处理非常大 300MB 的列表 在我的工作中 我每天都在处理这些列表 我可以用创可贴解决方案save load 黑客无处不在 但我更喜欢big
  • 为什么在 Python 中 math.floor(x/y) != x // y 表示两个可整除的浮点数?

    我一直在阅读有关Python中的除法和整数除法以及Python2与Python3中的除法之间的差异 在大多数情况下 这一切都是有道理的 Python 2 仅当两个值都是整数时才使用整数除法 Python 3 始终执行真除法 Python 2