2.3. Operazioni matematiche#

Python funziona come una calcolatrice fin da subito. Questa pagina copre gli operatori che userai più spesso: aritmetica sui numeri, confronti che producono valori booleani, operatori logici che combinano condizioni e operatori bit a bit per il lavoro a livello hardware.

2.3.1. Aritmetica#

Gli operatori aritmetici standard sui valori int e float:

  • + – addizione

  • - – sottrazione (oppure negazione, come prefisso: -x)

  • * – moltiplicazione

  • / – divisione. Restituisce sempre un float, anche quando entrambi gli operandi sono interi.

  • // – divisione intera. Restituisce il quoziente intero arrotondato verso meno infinito.

  • % – modulo (resto).

  • ** – elevamento a potenza (2 ** 10 è 1024).

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

L’aritmetica a tipi misti promuove automaticamente gli interi a float:

>>> 3 + 0.5
3.5

L’assegnazione aumentata combina l’operatore con = per un aggiornamento compatto sul posto:

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

La precedenza degli operatori segue l’ordine convenzionale: prima **, poi il - unario, poi *, /, // e %, infine + e -. Usa le parentesi quando hai dubbi – non costano nulla in fase di esecuzione.

2.3.2. Confronto#

Gli operatori di confronto restituiscono un bool (True o False):

  • == e != – uguale / diverso.

  • <, <=, >, >= – ordinamento.

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

L’ultimo esempio è un confronto concatenato ed è esattamente equivalente a 3 < 5 and 5 <= 5.

Avvertimento

= assegna; == confronta. L’espressione if x = 5: è un errore di sintassi proprio perché Python si rifiuta di confondere silenziosamente i due.

2.3.3. Logica booleana#

Tre operatori combinano i booleani:

  • andTrue solo quando entrambi i lati sono veri.

  • orTrue quando uno dei due lati è vero.

  • not – inverte un singolo booleano.

and e or operano in cortocircuito: smettono di valutare non appena il risultato è noto. False and slow_check() non chiama mai slow_check.

and e or restituiscono inoltre uno dei loro operandi anziché un letterale True o False, il che ti consente di scrivere valori predefiniti in modo compatto:

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

2.3.4. Operatori bit a bit#

Per il lavoro hardware – impacchettare campi di registro, mascherare bit, analizzare intestazioni di protocollo – ricorrerai agli operatori bit a bit. Agiscono sulla rappresentazione binaria di un int:

  • & – AND bit a bit

  • | – OR bit a bit

  • ^ – XOR bit a bit

  • ~ – NOT bit a bit (complemento a uno)

  • << – scorrimento a sinistra

  • >> – scorrimento a destra

Le forme letterali esadecimali e binarie sono comode per leggere e scrivere questi valori:

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

Per ciascuno esistono le forme aumentate: |=, &=, ^=, <<=, >>=.

Nota

and / or operano sui booleani (o sulla veridicità); & / | operano sui bit. Non confonderli. 0b1100 and 0b1010 si valuta come 0b1010 perché entrambi gli operandi sono veri – non quello che di solito vuoi quando manipoli i bit.

2.3.5. Funzioni integrate utili per i numeri#

Una manciata di funzioni integrate copre operazioni numeriche comuni che i soli operatori non coprono:

  • round() – l’intero più vicino, oppure il numero più vicino con ndigits cifre decimali quando viene fornito un secondo argomento. Restituisce un int per round(x) e un float per round(x, n). I casi di parità (0.5, 1.5, …) vengono arrotondati al numero pari più vicino, non sempre per eccesso.

  • divmod() – restituisce (quotient, remainder) in un’unica chiamata. Comodo per suddividere una quantità in unità (secondi in minuti-e-secondi, byte in pagine-e-offset).

  • pow() – equivale a ** nella forma a due argomenti. La forma a tre argomenti pow(base, exp, mod) calcola (base ** exp) % mod senza mai materializzare il gigantesco valore intermedio, il che è l’unico modo pratico per eseguire l’esponenziazione modulare con esponenti di grandi dimensioni.

>>> 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

Le conversioni da intero a stringa in basi diverse (bin, oct, hex) sono trattate in Metodi e formattazione delle stringhe.

2.3.6. Il modulo math#

Le funzioni matematiche comuni risiedono nel modulo math. Importalo una volta e chiama le sue funzioni tramite un nome puntato:

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

Il modulo math di MicroPython copre i soliti noti (sqrt, exp, log, sin, cos, tan, atan2, floor, ceil, pi, e, …). Per i numeri casuali, vedi il modulo random; per la manipolazione di bit in virgola fissa, gli operatori sopra sono di solito sufficienti.

2.3.7. Numeri complessi#

Per il lavoro numerico che richiede componenti immaginarie, Python ha un tipo complex con letterali a suffisso j (1 + 2j). Il modulo cmath rispecchia math per gli input complessi. Entrambi sono presenti nella maggior parte delle build di MicroPython ma raramente necessari per il lavoro con la camera; li menzioniamo principalmente affinché non siano una sorpresa se porti codice che li utilizza.