2011-08-24 49 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