2011-08-24 26 views
8

我希望3/2等于2不是1.5如何实现师带圆走向无穷的Python

我知道有该操作(不叫四舍五入)一个数学术语,但我不能现在回想起它。 无论如何,我怎么做,而不必做两个功能?

前的我不想:

answer = 3/2 then math.ceil(answer)=2 (why does math.ceil(3/2)=1?) 

前我做想要的东西:

"function"(3/2) = 2 
+1

如果你想3 2 = 2,这肯定不是分裂。 PS'math.ceil(3/2)= 1'因为'3/2 = 1'(整数除法),所以你是天花板1,而不是1.5 – NullUserException

+8

这** **是舍入的一个合法的形式,而术语因为它是[“向无穷圆”(或“轮远离零”)](http://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero)。大多数人都在不公平地殴打OP。是的,没有办法在本地Python中使用一个内置或fn来执行此操作。 – smci

+0

我敢肯定,他只是想确定,比如'divideup =拉姆达X,Y的函数:圆(浮动(X)/ Y)'或'divideup =拉姆达X,Y:math.ceil(浮点(X)/ y)'取决于他想要的四舍五入。 – agf

回答

2

当你把两个整数,结果是一个整数。
3/2等于1,而不是1.5
参见the documentation,注1:

对于(普通或长)整数除法,其结果是一个整数。结果总是向负无穷大舍入:1/2是0,(-1)/ 2是-1,1 /( - 2)是-1,(-1)/( - 2)是0.请注意,如果任一操作数是长整型,则结果为长整数,无论​​数值如何。

一旦您从该部门获得1,就无法将其转换为2

要获得1.5,您需要浮点除法:3.0/2
然后您可以致电math.ceil以获得2

你错了;没有任何数学函数可以分开,然后四舍五入。
你可以做的最好的事情是编写你自己的函数,它需要两个浮点数并调用math.ceil。在Python 3

+0

...或使用Python 3. Python 3默认进行浮点除法。 –

+0

@Null:那是因为我还没有完成。 – SLaks

+0

但是,如果你仔细阅读这个问题,OP特别要求一些不是四舍五入或天花板的东西 – NullUserException

5

积分划分:

3 // 2 == 1

非整数分频在Python 3:

3/2 == 1.5

什么你说的是不是所有的手段分裂。

+3

这给出1而不是2 – 2011-08-24 20:24:16

+0

在Python中<3,'3/2 == 1' – SLaks

+0

尽管您可能会指出Python 3默认会进行浮点除法,但Python 2.6在默认情况下是完整的。 –

1

你可能想要的是一样的东西:

math.ceil(3.0/2.0) 
# or 
math.ceil(float(3)/float(2)) 

你也可以从未来做一个导入:

from __future__ import division 
math.ceil(3/2) # == 2 

但是,如果你这样做,才能得到整数除法的当前行为你需要使用双斜线:

3 // 2 == 1 # True 
16

给出一个简短的答案...

Python只为本地运营商提供两种类型的划分:“真”划分和“向下划分”划分。所以你想要的不是一个单一的功能。但是,使用一些简短的表达式可以轻松实现许多不同类型的除法。

根据标题的要求:给定严格的整数输入,可以使用(a+(-a%b))//b来实现“向上舍入”的划分,并且可以使用更复杂的a//b if a*b<0 else (a+(-a%b))//b来实现“舍入零”划分。其中之一可能就是你想要的。至于为什么......


为了给出一个答案更长...

首先,让我回答有关为什么3/2==1math.ceil(3/2)==1.0的subquestion,通过解释如何Python的除法运算工作方式。有在玩两个主要问题...

float VS int师:在Python 2中,除法行为有所依据的输入的类型。如果ab都是整数,则a/b执行“舍入”或“楼层整数”除法(例如,3/2==1,但是-3/2==-2)。这相当于int(math.floor(float(a)/b))

但如果a至少一个和b是花车,Python的执行“真”分裂,并给你一个float结果(例如3.0/2==1.5-3.0/2==-1.5)。这就是为什么你有时会看到构造float(a)/b:它被用来强制真正的划分,即使两个输入都是整数(例如float(3)/2==1.5)。这就是为什么你的例子math.ceil(3/2)返回1.0,而math.ceil(float(3)/2)返回2.0。结果在达到math.ceil()之前已经被舍入。

“真师”默认:在2001年,它被决定(PEP 238)Python的除法运算应该改变,使其始终执行“真”师,不管输入是浮动或整数(如,这会使3/2==1.5)。为了不破坏现有的脚本,默认行为的改变被推迟到Python 3.0之前;为了在Python 2.x下获得这种行为,你必须通过在文件的顶部添加from __future__ import division来启用它的每个文件。否则,使用旧的依赖于类型的行为。

但是“往下”划分仍然经常需要,所以PEP并没有完全做到这一点。相反,它引入了一个新的分部运算符:a//b,其中总是执行舍入除法,即使输入包含浮点数。这可以在Python 2.2+和3.x下使用,而不需要做任何特殊的处理。


说出来的那个样子,师与舍入:

为了简化起见,下面的表达式都在整数工作时使用a//b运营商,因为它的行为相同在所有python版本下。另外,我假定0<=a%b<b如果b是正数,并且b<=a%b<=0如果b是负数。这就是Python的行为,但其他语言可能有略微不同的模数运算符。

四种舍入基本类型整数除法:

  • “四舍五入”又名“地板整数”又名“圆到负无穷大”记名表决:蟒蛇通过a//b提供这个本身。

  • “四舍五入”又名“天花板整数”又名“轮正无穷大”分裂:这可以通过int(math.ceil(float(a)/b))(a+(-a%b))//b来实现。后一个方程是有效的,因为-a%b为0,如果ab的倍数,否则我们需要添加到a以达到下一个最高倍数。 “

  • ”向零回零“又名”截断“分隔 - 这可以通过int(float(a)/b)来实现。这样做不使用浮点数是棘手的...因为Python只提供向下舍入的整数除法运算符,并且运算符具有类似的舍入偏差,所以我们没有任何非对称的大约0的非浮点运算符所以我能想到的唯一方法就是用圆整的方式构建一个分段表达式:a//b if a*b>0 else (a+(-a%b))//b

  • “圆离零”又名“圆(无论)无穷大”分裂 - 不幸的是,这比圆向零更棘手。我们无法再利用int运算符的截断行为,所以即使包含浮点运算符,我也无法想到简单的表达式。所以我必须用舍入到零的表达式的倒数,并使用a//b if a*b<0 else (a+(-a%b))//b

请注意,如果你只使用正整数,(a+b-1)//b提供围捕/远离零比任何上述解决方案的更有效,但分崩离析的底片。

希望能够帮助...并乐于进行编辑,如果任何人都可以提出更好的方程来回合/远离零。我发现那些我特别不满意的人。

+1

最后那些整数 - 这是要走的路。 – Owen

+0

感谢您的建议。我重构了我的答案以提供更多细节,并强调顶部的表达。希望我没有毁了答案:) –

+1

希望我可以加倍upvote ...优秀答案 – CrackerJack9

4

OP的问题的意图是“如何在Python中实现无限循环的分割”(建议您更改标题)。

根据IEEE-754 standard(阅读this overview),这是一个完全合法的舍入模式,其术语是“向无限大圆”(或“从零开始舍入”)。这9个投注中的大部分都不公平地打败了OP。是的,在本地Python中没有单一功能的方式来执行此操作,但我们可以使用round(float(a)/b)或其他子类numbers.Number并覆盖__div__()

OP将需要澄清他们是否希望-3/2舍入-2或-1(或不关心负操作数)。既然他们已经表示他们不想要四舍五入,我们可以推断-3/2应该是-2。

足够的理论。对于实现:

  • 如果你只是想为快速和肮脏的单行解决方案圆走向无穷,使用round(float(a)/b)
  • math.ceil(float(a)/b)给你圆向上,你说你不要

  • 但如果这是你的默认除法运算中,或者你正在做大量的这个,然后做像下面的伪代码:inherit from one of the subclasses of numbers.Number Real, Rational or Integral (new in 2.6),重新定义__div__()或者定义非默认选项__divra__()操作。你可以定义一个班级成员或班级方法rounding_mode并在部门中查找。尽管如此,请注意__rdiv__()并与普通花车混合。

import numbers 

class NumberWithRounding(numbers.Integral): 
    # Here you could implement a classmethod setRoundingMode() or member rounding_mode 
    def __div__(self,other): 
     # here you could consider value of rounding_mode, or else hardwire it like: 
     return round(float(self)/other) 
    # You also have to raise ImplementationError/ pass/ or implement the other 31 
    # methods for Float: __abs__(),...,__xor__() Just shortcut that for now... 
1

我认为你正在寻找的东西是这样的:

假设你有X(3)和y(2),

result = (x + y - 1) // y;

这相当于没有使用浮点的天花板。

当然,Y不能为0

1

整数除法与天花板四舍五入(到+ Inf文件),地板四舍五入(至-Inf)和截短(0)是在gmpy2可用。

>>> gmpy2.c_div(3,2) 
mpz(2) 
>>> help(gmpy2.c_div) 
Help on built-in function c_div in module gmpy2: 
c_div(...) 
    c_div(x,y): returns the quotient of x divided by y. The quotient 
    is rounded towards +Inf (ceiling rounding). x and y must be integers. 
>>> help(gmpy2.f_div) 
Help on built-in function f_div in module gmpy2: 
f_div(...) 
    f_div(x,y): returns the quotient of x divided by y. The quotient 
    is rounded towards -Inf (floor rounding). x and y must be integers. 
>>> help(gmpy2.t_div) 
Help on built-in function t_div in module gmpy2: 
t_div(...) 
    t_div(x,y): returns the quotient of x divided by y. The quotient 
    is rounded towards 0. x and y must be integers. 
>>> 

gmpy2可在http://code.google.com/p/gmpy/

(声明:我gmpy和gmpy2当前维护者)

0

首先,要使用浮点除法的参数。用途:

from __future__ import division 

如果你总是希望围捕,所以f(3/2)==2f(1.4)==2,然后你想fmath.trunc(math.ceil(x))

如果你想要得到的最接近的整数,但有关系围捕,那么你要math.trunc(x + 0.5)。那样f(3/2)==2f(1.4)==1