2.3. 數學運算

Python 開箱即可當作計算機使用。本頁涵蓋你最常用到的運算子:數字的算術運算、產生布林值的比較運算、組合條件的邏輯運算子,以及用於硬體層級工作的位元運算子。

2.3.1. 算術運算

作用於 intfloat 值的標準算術運算子:

  • + -- 加法

  • - -- 減法(或作為前綴時表示取負:-x

  • * -- 乘法

  • / -- 除法。永遠 回傳 float,即使兩個運算元都是整數也一樣。

  • // -- 向下取整除法。回傳向負無窮大取整的整數商。

  • % -- 取模(餘數)。

  • ** -- 次方(2 ** 10 等於 1024)。

>>> 7 / 2
3.5
>>> 7 // 2
3
>>> -7 // 2
-4
>>> 7 % 2
1
>>> 2 ** 16
65536

混合型別的算術運算會自動將整數提升為浮點數:

>>> 3 + 0.5
3.5

增量指派將運算子與 = 結合,以進行精簡的就地更新:

counter = 0
counter += 1                # equivalent to counter = counter + 1
counter *= 2                # works for *= /= //= %= **= too

運算子優先順序遵循慣例次序:先是 **,接著是一元 -,然後是 *///%,最後是 +-。不確定時就使用括號 -- 它們在執行時不會帶來任何成本。

2.3.2. 比較運算

比較運算子回傳 boolTrueFalse):

  • ==!= -- 等於 / 不等於。

  • <<=>>= -- 排序。

>>> 3 == 3
True
>>> 3 == 3.0
True
>>> 3 < 5 <= 5
True

最後一個範例是 連鎖 比較,完全等同於 3 < 5 and 5 <= 5

警告

= 用於指派;== 用於比較。if x = 5: 這個運算式正是語法錯誤,因為 Python 拒絕悄悄地混淆這兩者。

2.3.3. 布林邏輯

三個運算子可組合布林值:

  • and -- 只有當兩邊都為真時才是 True

  • or -- 當任一邊為真時即為 True

  • not -- 反轉單一布林值。

andor短路求值:一旦結果已知就停止求值。False and slow_check() 永遠不會呼叫 slow_check

andor 也會回傳其中一個運算元,而非字面的 TrueFalse,這讓你能精簡地撰寫預設值:

name = user_name or "anonymous"   # "" / 0 / None are falsy

2.3.4. 位元運算子

進行硬體工作時 -- 打包暫存器欄位、遮罩位元、解析協定標頭 -- 你會用到位元運算子。它們作用於 int 的二進位表示:

  • & -- 位元 AND

  • | -- 位元 OR

  • ^ -- 位元 XOR

  • ~ -- 位元 NOT(一補數)

  • << -- 左移

  • >> -- 右移

讀寫這些值時,十六進位與二進位的字面形式很方便:

>>> 0b1100 & 0b1010
8                              # 0b1000
>>> 0b1100 | 0b1010
14                             # 0b1110
>>> 0xFF ^ 0x0F
240                            # 0xF0
>>> 1 << 8
256
>>> (0xABCD >> 8) & 0xFF
171                            # extract the high byte

每個運算子都有對應的增量形式:|=&=^=<<=>>=

備註

and / or 作用於布林值(或真假性);& / | 作用於位元。不要把它們搞混。0b1100 and 0b1010 求值結果為 0b1010,因為兩個運算元都為真 -- 這通常不是你在操作位元時想要的結果。

2.3.5. 實用的數字內建函式

有少數幾個內建函式涵蓋了單靠運算子無法完成的常見數值運算:

  • round() -- 最接近的整數,或在給定第二個引數時取最接近的 ndigits 小數位數。round(x) 回傳 intround(x, n) 回傳 float。位於正中間的值(0.51.5、……)會四捨五入到最接近的偶數,而非總是進位。

  • divmod() -- 一次呼叫即回傳 (quotient, remainder)。便於將某個量拆分成多個單位(將秒拆成分與秒、將位元組拆成頁與偏移量)。

  • pow() -- 雙引數形式與 ** 相同。三引數形式 pow(base, exp, mod) 會計算 (base ** exp) % mod,且過程中絕不會具體產生龐大的中間值,這是針對大指數進行模冪運算唯一可行的方法。

>>> round(3.7)
4
>>> round(3.14159, 2)
3.14
>>> round(0.5)               # ties go to even, not always up
0
>>> round(1.5)
2

>>> divmod(125, 60)          # 125 seconds = 2 min, 5 sec
(2, 5)
>>> minutes, seconds = divmod(125, 60)

>>> pow(3, 4)                # same as 3 ** 4
81
>>> pow(3, 100, 7)           # (3 ** 100) mod 7, efficient
4

整數轉字串的進位制轉換(binocthex)涵蓋於 字串方法與格式化 中。

2.3.6. math 模組

常見的數學函式存在於 math 模組中。匯入它一次,然後透過點號名稱呼叫其函式:

import math

print(math.sqrt(2))              # 1.4142135
print(math.sin(math.pi / 2))     # 1.0
print(math.floor(3.7))           # 3
print(math.log(100, 10))         # 2.0

MicroPython 的 math 模組涵蓋了常見的那些函式(sqrtexplogsincostanatan2floorceilpie、……)。需要亂數時,請參閱 random 模組;至於定點位元操作,上述運算子通常就足夠了。

2.3.7. 複數

對於需要虛數成分的數值工作,Python 有一個 complex 型別,使用 j 後綴字面值(1 + 2j)。cmath 模組對複數輸入提供了與 math 對應的功能。兩者在大多數 MicroPython 建置中都存在,但相機工作鮮少需要用到;在此提及主要是為了讓你在移植使用它們的程式碼時不會感到意外。