【问题标题】:ceil function with high precision [duplicate]高精度的ceil函数[重复]
【发布时间】:2014-09-10 20:36:57
【问题描述】:

如何以高精度将数字四舍五入到下一个整数?

Input: var1 = (8193/4096) # var1 = 2.00024414063
Output: 3 # As an integer

>>> var1 = 8193/4096
>>> import math
>>> math.ceil(var1)
2.0
>>> math.ceil(8193/4096)
2.0
>>> import numpy
>>> numpy.ceil(8193/4096)

我怎样才能优雅地做这个操作?

【问题讨论】:

  • x/y + 1 就足够了吗?
  • @ajcr 如果8192/4096 怎么办?然后我希望答案是2 而不是3
  • 我忘了检查是否有重复项……哎。嗯,现在关门了。
  • @Veedrac 重复的问题专门要求operator 用于在Python 3 上使用的除法。我的问题是在Python 2 中询问precision
  • @Sunil What's difference?

标签: python python-2.7 integer-division ceil


【解决方案1】:

在 Python 2 中,这是:

>>> var1 = 8193/4096

没有做你认为它做的事。在 Python 2 中,两个整数相除总是返回一个整数(截断)作为结果。

>>> 8193/4096
2

...然后在 2 上调用 math.ceil() 返回 2。

将您的一个或两个值转换为浮点值,它会做您喜欢的事情:

>>> v = 8193/4096.0
>>> v
2.000244140625
>>> math.ceil(v)
3.0

替代方案:

a) 切换到 Python 3,其中除法的行为确实如您所愿:

bgporter@zappa:~$ python3
Python 3.4.0 (default, Apr 11 2014, 13:05:18)
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 8193/4096
2.000244140625
>>>

b) 像这样在 Python 2 上启用 Python 3 的除法:

bgporter@varese ~:python
Python 2.7.5 (default, Mar  9 2014, 22:15:05)
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from __future__ import division
>>> 8193/4096
2.000244140625

【讨论】:

  • from __future__ import division
  • 啊,好点子。编辑以反映这一点。
【解决方案2】:

问题:您当前正在进行整数除法,这将隐式计算商的下限并为您提供整数值。

解决方案:将一个元素(除数或被除数)转换为float first:

math.ceil( float(8193)/4096 ) 
3.0

OR:只需将.0 添加到其中一个数字的末尾即可使其变为浮点数,如下所示:

math.ceil( 8193.0/4096 )
3.0

OR:从__future__ 模块导入division 功能,默认允许Python 3 除法:

from __future__ import division
math.ceil( 8193.0/4096 )

Python 3:然而,在 Python 3 中,/ 是真正的划分,因此您不必担心上述问题。在那里,如果您想复制遇到的问题,则必须使用 // 进行整数除法。 // 功能在所有 Python 版本中都是相同的。

【讨论】:

  • from __future__ import division
  • 感谢@Adam,更新了!
【解决方案3】:
-(-8193/4096)

精确整数除法,并向上四舍五入。

因此这比涉及浮点数要好。

只是因为a/b楼层,所以-a/b楼层否定,所以-(-a/b)给你你想要的答案。

要支持 Python 3(总是一个好主意),请使用 -(-8193//4096)


这是一个击败 ceil 的简单示例:

>>> -(-10**17 // 3)
33333333333333334
>>> int(ceil(10**17 / 3.0))
33333333333333332

【讨论】:

  • 我收回我之前的批评——我错过了这是 Python2。然而,这有点神秘的符号而不是 Python 编程。这与使用 ~~some_int 而不是 abs(some_int) 的思路相同
  • 请注意,// 也适用于 Python 2。
  • @AdamSmith ~~x 只是给了x...无论如何,我同意但是它比使用浮点数要好得多,最好将它包装在一个函数中或评论它并忍受潜在的混乱。 :)
  • @Veedrac 哎呀你是对的,~~xfloor(x) 不是 abs(x)
  • 我强烈反对这种方法。通过引入神秘的双重否定来过早地进行优化与我想要编写(或维护)的代码完全相反
【解决方案4】:

另一种纯整数方法,对我来说比双重否定方法更直观,尽管它仅适用于正数y

def myceil(x, y):
    return (x + y - 1) // y

【讨论】:

  • @Veedrac 谢谢,更新了答案
猜你喜欢
  • 1970-01-01
  • 2018-11-26
  • 1970-01-01
  • 2012-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多