舍入整数除法

gae*_*fan 23 python rounding integer-division

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

skip = int(round(1.0 * total / surplus))
Run Code Online (Sandbox Code Playgroud)

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

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

Joh*_*hin 35

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

(n + d // 2) // d,n股息在哪里,d是除数.

在最近的CPythons中,类似(((n << 1) // d) + 1) >> 1或等效的替代品(((n * 2) // d) + 1) // 2可能是SLOWER,其中a int是像旧的一样实现的long.

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

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

  • +1这种方法比位移方法更具可读性,并且在Py 2.7上也更快(在时间测试中). (2认同)

Amb*_*ber 6

skip = (((total << 1) // surplus) + 1) >> 1
Run Code Online (Sandbox Code Playgroud)

将剩下的东西换成有效的东西有效地乘以2,向右移动一位除以两个向下舍入.在中间添加一个使得如果结果将高于.5小数部分,"向下舍入"实际上是四舍五入.

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

skip = int((1.0*total/surplus) + 0.5)
Run Code Online (Sandbox Code Playgroud)

除了一切由2 multplied,再后来除以2,这是你可以用整数运算(因为位移位不需要浮点)做的.


Dan*_*l K 6

灵感来自zhmyh的答案答案,即

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

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

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

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

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

如果您想知道如何divmod定义:根据其文档

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

因此,我们坚持使用OP所要求的整数运算.