比較 Python 與除法相關的運算子與函式 – /、//、% 與 divmod

Jo-Yu Liao
6 min readApr 16, 2020

--

Python2 & Python3

Python 有內建的運算子與方法可以計算除法、得到商以及餘數。本篇主要介紹 ///%運算子(Operator)以及內建函式(built-in function,BIF)divmod

除法運算子

在 Python 2 中, / 運算子有 2 種除法:

1. 向下取整除法(floor division)

在除數、被除數皆為整數的時候, / 運算子為「向下取整除法」(floor division) — 除完後會執行 floor 函式無條件捨去小數點。比方說 2/3 較精確的計算結果應該是 0.6666666666666666 ,但在 Python2 會無條件捨去小數點,所以結果為 0:

2/3 = 0

2. 真除法(true division)

如果想用我們平常算數的「真除法」(true division)得到近似的浮點數(float)或複數(complex)結果?只要被除數、除數有任一的型別為浮點數或複數即可:

float(2)/3 = 0.6666666666666666
2 / 3+0i

Python2 / 運算子這種混合「向下取整除法」和「真除法」的除法特性,被稱為經典除法」(classic division)。這會導致在比較運算結果時容易出錯,比方說:

1 / 2 != 1.0 / 2.0
哪泥 ???????

所幸,這種情況到 Python3 就改善惹! *\(≧▽≦)/* Python3 的/運算子只保留「真除法」,也就是說不管除數、被除數的型別都可以得到更精確的結果

2/3 = 0.6666666666666666

所以在 Python2 會出現的1/2 != 1.0/2.0問題也被解決囉!

但如果想用「向下取整除法」呢?可以用//運算子:

//運算子不管除數、被除數的型別為何,回傳的都是無條件捨去的結果。如果都是整數,就回傳整數,如果有任一為浮點數,則回傳浮點數:

1 // 2 v.s 1 // 2.0

說完除法運算子,如果想得到餘數(remainder)呢?請用 % 餘除運算子:

% 運算子範例

那如果我想要同時得到商還有餘數呢?可以用內建函數 divmod

divmod(被除數, 除數) = (被除數 // 除數, 被除數 % 除數) = (商, 餘數)

比方說 2 / 3 = 0 餘 2,10/3 = 3 餘 1,用 divmod 可以得到下面結果:

divmod

這可以用在什麼場景呢?因為 /運算子只能取得近似值,在一些循環小數會有進位的問題,比方說 1/90 應該是 0.1(1) ,(1)表示循環小數 1,但在 Python 會變成:

1/90 自動進位
哪泥 ???????

如果要精確的循環小數,就要搭配 divmod 實現長除法(Long Division),有興趣的話可以試試 leetcode 第 166 題 fraction-to-recurring-decimal

另外如果判斷是不是質數也可以用 divmod。比方說 www.tutorialspoint.comdivmod 判斷質數的範例:

# 想判斷 num 是不是質數,以 num = 11 為例
num = 11
a = num
# counter the number of remainders with value zero
count = 0 # 因數的數量
while a != 0:
q, r = divmod(num, a) # q 為商, r 為餘數
a -= 1
if r == 0: # 可被整除
count += 1
if count > 2: # 因數除了 1 & num 還有其他整數
print(num, 'is not Prime')
else:
print(num, 'is Prime')

以上是///% 運算子及內建函式divmod的比較,感謝閱讀(*´∀`)~♥

--

--