Python 整数除法舍入
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3950372/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Round with integer division
提问by gaefan
Is there is a simple, pythonic way of rounding to the nearest whole number without using floating point? I'd like to do the following but with integer arithmetic:
是否有一种简单的、pythonic 的方法可以在不使用浮点的情况下舍入到最接近的整数?我想做以下但使用整数运算:
skip = int(round(1.0 * total / surplus))
==============
==============
@John: Floating point is not reproducible across platforms. If you want your code to pass tests across different platforms then you need to avoid floating point (or add some hacky espilon stuff to your tests and hope it works). The above may be simple enough that it would be the same on most/all platforms, but I'd rather not make that determination as it is easier to avoid floating point altogether. How is that "not in the spirit of Python"?
@John:浮点不能跨平台重现。如果您希望您的代码在不同平台上通过测试,那么您需要避免浮点(或在您的测试中添加一些 hacky espilon 内容并希望它有效)。以上可能很简单,在大多数/所有平台上都是一样的,但我宁愿不做这个决定,因为完全避免浮点更容易。这“不符合 Python 的精神”是怎么回事?
采纳答案by John Machin
You can do this quite simply:
你可以很简单地做到这一点:
(n + d // 2) // d, where nis the dividend and dis the divisor.
(n + d // 2) // d,其中n是被除数,d是除数。
Alternatives like (((n << 1) // d) + 1) >> 1or the equivalent (((n * 2) // d) + 1) // 2may be SLOWER in recent CPythons, where an intis implemented like the old long.
在最近的 CPython 中,类似(((n << 1) // d) + 1) >> 1或等效的替代方案(((n * 2) // d) + 1) // 2可能会更慢,其中 anint的实现与旧的long.
The simple method does 3 variable accesses, 1 constant load, and 3 integer operations. The complicated methods do 2 variable accesses, 3 constant loads, and 4 integer operations. Integer operations are likely to take time which depends on the sizes of the numbers involved. Variable accesses of function locals don't involve "lookups".
简单方法执行 3 次变量访问、1 次常量加载和 3 次整数运算。复杂的方法执行 2 次变量访问、3 次常量加载和 4 次整数运算。整数运算可能需要时间,这取决于所涉及数字的大小。局部函数的变量访问不涉及“查找”。
If you are really desparate for speed, do benchmarks. Otherwise, KISS.
如果你真的很渴望速度,那就做基准测试。否则,吻。
回答by Amber
skip = (((total << 1) // surplus) + 1) >> 1
Shifting things left by one bit effectively multiplies by two, shifting things right by one bit divides by two rounding down. Adding one in the middle makes it so that "rounding down" is actually rounding up if the result would have been above a .5 decimal part.
将事物左移一位有效地乘以二,将事物右移一位除以二舍入。如果结果高于 0.5 小数部分,则在中间添加一个可以使“向下舍入”实际上是向上舍入。
It's basically the same as if you wrote...
和你写的基本一样...
skip = int((1.0*total/surplus) + 0.5)
except with everything multplied by 2, and then later divided by 2, which is something you can do with integer arithmetic (since bit shifts don't require floating point).
除了所有的东西乘以 2,然后再除以 2,这是你可以用整数算法做的事情(因为位移不需要浮点数)。
回答by rubik
This should work too:
这也应该有效:
def rint(n):
return (int(n+.5) if n > 0 else int(n-.5))
回答by hobbs
Simply take care of the rounding rule before you ever divide. For the simplest round-half-up:
在进行除法之前,只需注意舍入规则即可。对于最简单的四舍五入:
if total % surplus < surplus / 2:
return total / surplus
else:
return (total / surplus) + 1
Tweak a little bit if you need to do a proper round-to-even.
如果您需要进行适当的舍入到偶数,请稍微调整一下。
回答by rmnff
Yet another funny way:
还有一个有趣的方式:
q, r = divmod(total, surplus)
skip = q + int(bool(r))
回答by Daniel K
Inspired by zhmyh's answeranswer, which is
受到zhmyh 的回答的启发,这是
q, r = divmod(total, surplus)
skip = q + int(bool(r)) # rounds to next greater integer (always ceiling)
, I came up with the following solution:
,我想出了以下解决方案:
q, r = divmod(total, surplus)
skip = q + int(2 * r >= surplus) # rounds to nearest integer (floor or ceiling)
Since the OP asked for rounding to the nearestwhole number, zhmhs's solution is in fact slightly incorrect, because it always rounds to the next greaterwhole number, while my solution works as demanded.
由于 OP 要求四舍五入到最接近的整数,因此 zhmhs 的解决方案实际上有点不正确,因为它总是四舍五入到下一个更大的整数,而我的解决方案按要求工作。
(If you feel that my answer should better have been an edit or comment on zhmh's answer, let me point out that my suggested edit for it was rejected, because it should better have been a comment, but I do not have enough reputation yet for commenting!)
(如果你觉得我的回答最好是对 zhmh 的回答进行编辑或评论,让我指出我建议的编辑被拒绝了,因为它最好是评论,但我还没有足够的声誉评论!)
In case you wonder how divmodis defined: According to its documentation
如果您想知道如何divmod定义:根据其文档
For integers, the result is the same as
(a // b, a % b).
对于整数,结果与 相同
(a // b, a % b)。
We therefore stick with integer arithmetic, as demanded by the OP.
因此,我们按照 OP 的要求坚持使用整数算术。

