舍入整数除法

时间:2010-10-16 19:15:40

标签: python rounding integer-division

是否有一种简单的pythonic方法可以在不使用浮点的情况下舍入到最接近的整数?我想做以下但是使用整数运算:

skip = int(round(1.0 * total / surplus))

==============

@John:浮点数不能跨平台重现。如果您希望代码在不同平台上传递测试,那么您需要避免浮点(或者在测试中添加一些hacky espilon东西并希望它能够工作)。以上可能很简单,在大多数/所有平台上都是相同的,但我宁愿不做出这个决定,因为更容易完全避免浮点数。那“不符合Python的精神”?

6 个答案:

答案 0 :(得分:35)

你可以很简单地做到这一点:

(n + d // 2) // d,其中n是被除数,d是除数。

(((n << 1) // d) + 1) >> 1或同等(((n * 2) // d) + 1) // 2等替代品在最近的CPythons中可能会降低,其中int的实施方式与旧的long相同。

简单方法执行3次变量访问,1次常量加载和3次整数运算。复杂的方法进行2次变量访问,3次常量加载和4次整数运算。整数操作可能需要一些时间,这取决于所涉及的数字的大小。函数局部变量访问不涉及“查找”。

如果你真的对速度感到绝望,那就做基准吧。否则,KISS。

答案 1 :(得分:6)

skip = (((total << 1) // surplus) + 1) >> 1

将剩下的东西有效地移动一两倍,将事物向右移动一位除以两个向下舍入。在中间添加一个使得如果结果将高于0.5小数部分,“向下舍入”实际上是四舍五入。

它与你写的基本相同......

skip = int((1.0*total/surplus) + 0.5)

除了所有数据乘以2,然后再除以2,这是你可以用整数运算做的事情(因为位移不需要浮点数)。

答案 2 :(得分:6)

受到zhmyh's answer回答的启发,这是

q, r = divmod(total, surplus)
skip = q + int(bool(r)) # rounds to next greater integer (always ceiling)

,我提出了以下解决方案:

q, r = divmod(total, surplus) 
skip = q + int(2 * r >= surplus) # rounds to nearest integer (floor or ceiling)

由于OP要求舍入到最近的整数,zhmhs的解决方案实际上稍微不正确,因为它总是向下一个更大整数进行舍入,而我的解决方案按要求运行。

(如果你觉得我的答案最好是对zhmh的答案进行编辑或评论,请允许我指出我对它的建议编辑被拒绝,因为它最好是评论,但我做还没有足够的声誉来评论!)

如果你想知道如何定义divmod:根据documentation

  

对于整数,结果与(a // b, a % b)相同。

因此,我们坚持使用整数运算,如OP所要求的那样。

答案 3 :(得分:2)

又一个有趣的方式:

q, r = divmod(total, surplus)
skip = q + int(bool(r))

答案 4 :(得分:0)

在划分之前,只需要处理舍入规则。对于最简单的圆形半场:

if total % surplus < surplus / 2:
    return total / surplus
else:
    return (total / surplus) + 1

如果你需要做一个适当的圆到均匀,可以稍微调整一下。

答案 5 :(得分:-2)

这也应该有效:

def rint(n):
    return (int(n+.5) if n > 0 else int(n-.5))