python - 如何在Python中使用Round-towards-Infinity实现除法

标签 python math floating-point rounding division

我希望3/2等于2而不是1.5

我知道该操作有一个数学术语(不称为舍入),但是我现在不记得它了。
无论如何,我该怎么做而不必执行两个功能?

我不想要的东西:

answer = 3/2 then math.ceil(answer)=2 (why does math.ceil(3/2)=1?)  

我想要的东西前:
 "function"(3/2) = 2

最佳答案

简短回答...

Python仅为两种类型的除法提供 native 运算符:“真”除法和“舍入”除法。因此,您所需的功能无法作为一个单一功能使用。但是,可以使用一些短表达式轻松实现许多不同类型的舍入除法。

根据标题的要求:给定严格的整数输入,可以使用(a+(-a%b))//b实现“舍入”除法,而可以使用更复杂的a//b if a*b<0 else (a+(-a%b))//b实现“从零舍入”除法。其中之一可能就是您想要的。至于为什么...

要给出更长的答案...

首先,让我通过解释Python除法运算符的工作方式回答有关3/2==1math.ceil(3/2)==1.0的子问题。有两个主要问题在起作用...

floatint划分:在Python 2下,划分的行为取决于输入类型。如果ab都是整数,则a/b执行“舍入”或“底整数”除法(例如3/2==1,但-3/2==-2)。这等效于int(math.floor(float(a)/b))

但是,如果ab中至少有一个是浮点数,Python将执行“true”除法,并为您提供float结果(例如3.0/2==1.5-3.0/2==-1.5)。这就是为什么有时会看到float(a)/b构造的原因:即使两个输入都是整数(例如float(3)/2==1.5),它也被用于强制进行真除法。这就是为什么示例math.ceil(3/2)返回1.0,而math.ceil(float(3)/2)返回2.0的原因。结果已经四舍五入,甚至没有达到math.ceil()

默认为“真除法” :2001年,决定(PEP 238)应该更改Python的除法运算符,以便始终执行“真”除法,而不管输入是浮点数还是整数(例如,这样做3/2==1.5)。为了不破坏现有脚本,将默认行为的更改推迟到Python 3.0之前进行;为了在Python 2.x下获得此行为,您必须通过在文件顶部添加from __future__ import division来按文件启用它。否则,将使用旧的类型相关行为。

但是仍然经常需要“向下舍入”划分,因此PEP并没有完全做到这一点。相反,它引入了一个新的除法运算符:a//b,即使输入包含浮点数,该运算符也始终执行舍入除法。在Python 2.2+和3.x下都可以使用它而无需做任何特殊的事情。

这样一来,舍入取整:

为了简化操作,下面的表达式在处理整数时都使用a//b运算符,因为它在所有python版本中的行为都相同。同样,我假设如果0<=a%b<b为正,则为b,如果b为负,则为b<=a%b<=0。这就是Python的行为方式,但其他语言的模运算符可能略有不同。

舍入的整数除法的四种基本类型:

  • “向下取整” aka“底整数” aka“减去负无穷大”除法:python通过a//b原生提供此功能。
  • “向上舍入” aka“天花板整数” aka“正整数到无穷大”除法:这可以通过int(math.ceil(float(a)/b))(a+(-a%b))//b实现。后一个方程之所以有效,是因为如果-a%ba的倍数,则b为0;否则,我们需要将其添加到a才能达到下一个最高倍数。
  • “朝零舍入” 又名“截断”除法-这可以通过int(float(a)/b)实现。在不使用浮点数的情况下执行此操作比较棘手...由于Python仅提供向下舍入的整数除法,并且%运算符具有类似的向下舍入偏差,因此我们没有任何非浮点运算符,它们对称地在0左右舍入因此,我唯一想到的方法是从上舍入和下舍入构造一个分段表达式:a//b if a*b>0 else (a+(-a%b))//b
  • “从零开始舍入” 又名“到(或)无限舍入”除法-不幸的是,这甚至比从零开始舍入更为棘手。我们再也无法利用int运算符的截断行为了,因此即使包含浮点运算,我也无法想到一个简单的表达式。因此,我必须将舍入到零的表达式取反,并使用a//b if a*b<0 else (a+(-a%b))//b

  • 请注意,如果您仅使用正整数,则(a+b-1)//b会比上述任何一种解决方案更有效地提供四舍五入/远离零的功能,但会导致负数的产生。

    希望对您有帮助...并且乐于进行编辑,如果有人可以提出更好的方程,说明从零舍入/舍入为零。我发现我特别不满意的那些。

    关于python - 如何在Python中使用Round-towards-Infinity实现除法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7181757/

    相关文章:

    opengl - 四元数旋转,试图围绕他的轴旋转一个对象

    .net - Math.Max 与 Enumerable.Max

    c - 高效计算 (a - K)/(a + K) 并提高准确性

    python - 使用 openCV 通过网络摄像头制作实时草图

    python - 3D旋转以连 catch 和圆柱体

    python - 提高Python比较两个列表的性能

    math - 如何计算已知半径和圆心的圆上的点

    c - 以 float 形式打印数组,其中大小取决于用户输入

    python - 如果我有 PYC 文件,是否需要安装 Python?

    python - Django - 当前 URL 与这些中的任何一个都不匹配