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.
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,这是你可以用整数运算(因为位移位不需要浮点)做的.
灵感来自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所要求的整数运算.