是否有一种简单的pythonic方法可以在不使用浮点的情况下舍入到最接近的整数?我想做以下但是使用整数运算:
skip = int(round(1.0 * total / surplus))
==============
@John:浮点数不能跨平台重现。如果您希望代码在不同平台上传递测试,那么您需要避免浮点(或者在测试中添加一些hacky espilon东西并希望它能够工作)。以上可能很简单,在大多数/所有平台上都是相同的,但我宁愿不做出这个决定,因为更容易完全避免浮点数。那“不符合Python的精神”?
答案 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))