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.