簡體   English   中英

在 Python 中,在整數除法中向零舍入的好方法是什么?

[英]In Python, what is a good way to round towards zero in integer division?

1/2

0

正如它應該。 然而,

-1/2

-1

,但我希望它向 0 舍入(即我希望 -1/2 為 0),無論它是正數還是負數。 最好的方法是什么?

做浮點除法然后轉換為int。 不需要額外的模塊。

蟒蛇3:

>>> int(-1 / 2)
0
>>> int(-3 / 2)
-1
>>> int(1 / 2)
0
>>> int(3 / 2)
1

蟒蛇2:

>>> int(float(-1) / 2)
0
>>> int(float(-3) / 2)
-1
>>> int(float(1) / 2)
0
>>> int(float(3) / 2)
1

Python 的默認整數除法是返回下限(向負無窮大),無法改變它。 您可以閱讀BDFL 的原因。

要進行“四舍五入”除法,您可以使用:

>>> a=1
>>> b=2
>>> (a+(-a%b))//b
1
>>> a,b=-1,2
>>> (a+(-a%b))//b
0

要向零截斷並保持整數除法,如果 a 或 b 為負,則使用(a+(-a%b))//b如果兩者均為正,則使用默認除法。

這將進行整數除法並始終向零舍入:

>>> a=1
>>> b=2
>>> a//b if a*b>0 else (a+(-a%b))//b
0
>>> a=-1
>>> b=2
>>> a//b if a*b>0 else (a+(-a%b))//b
0
>>> a,b=-3,2
>>> a//b if a*b>0 else (a+(-a%b))//b
-1
>>> a,b=3,2
>>> a//b if a*b>0 else (a+(-a%b))//b
1

腳注

有趣的是,C99 聲明向零舍入是默認值:

#include <stdio.h>
int main(int argc, const char * argv[])
{

    int a=-3;
    int b=2;
    printf("a=%d, b=%d, a/b=%d\n",a,b,a/b);
    a=3;
    printf("a=%d, b=%d, a/b=%d\n",a,b,a/b);
    return 0;
}

印刷:

a=-3, b=2, a/b=-1
a=3, b=2, a/b=1

對於它的價值,我自己最喜歡的解決方案是這個。 僅整數算術,單除法,以及其他所有線性時間:

def integer_divide_towards_zero(a, b):
    return -(-a // b) if a < 0 else a // b

這假設b是正數,但在我見過的大多數應用程序中都是如此。 如果您也需要處理負b ,那么該函數會變得稍微復雜一些:

def integer_divide_towards_zero(a, b):
    return -(-a // b) if (a < 0) ^ (b < 0) else a // b

一些示例輸出:

>>> integer_divide_towards_zero(11, 3)
3
>>> integer_divide_towards_zero(-11, 3)
-3
>>> integer_divide_towards_zero(6, 3)
2
>>> integer_divide_towards_zero(-6, 3)
-2
>>> integer_divide_towards_zero(11, -3)
-3
>>> integer_divide_towards_zero(-11, -3)
3

嘗試這個。 僅適用於大於 -1 的數字

import math

x = .5
y = -.5

print math.floor(math.fabs(x))
>> 0

print math.floor(math.fabs(y))
>> 0

在我看來,執行此操作的正確代碼太晦澀,無法編寫為 1-liner。 所以我把它放在一個函數中,比如:

def int0div(a, b):
    q = a // b
    if q < 0 and b*q != a:
        q += 1
    return q

好的特性:它適用於任何大小的 int,除非必要,否則不對原始 ( a//b ) 結果進行任何調整,只進行一個除法( %也在幕后進行除法),並且不創建任何大於輸入的整數。 這些在您的應用程序中可能重要也可能無關緊要; 如果您使用“大”整數,它們會變得更加重要(對於速度)。

提出一些替代想法:

將數字 [abs(x)/x] 的符號乘以 abs(x)/2

(abs(x)/x)*(abs(x)/2)

執行加法,但如果數字小於零,則加一使其更接近於 0。

x/2 + int(x<0)

您還可以使用Decimal模塊作為標准 Python 庫的一部分。

具體來說,“整數除法運算符 // 的行為類似,返回真商的整數部分(向零截斷)而不是其底數,以保留通常的身份 x == (x // y) * y + x %y:"

>>> -7 // 4
-2
>>> Decimal(-7) // Decimal(4)
Decimal('-1')

另外,看看 舍入模式,因為他們有很多方法可以查看/舍入您的信息 - 天花板、向下、地板、半向下、半偶數、半向上、向上和 05 向上舍入。

十進制是為了解決期望小數解決方案的世界中二進制數學的傳統問題而編寫的

為什么要重新發明輪子,當有一個非常好的 math.trunc() 函數時?

import math
print(math.trunc(-3.5))
>>-3
print(math.trunc(3.5))
>>3

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM