Vai al contenuto
Leo

Parte I — Le basi

Capitolo 3 — I numeri

I numeri sono ovunque: punteggi, prezzi, misure, conteggi. Leo li prende sul serio e offre più tipi di numero, ciascuno adatto a un mestiere. In questo capitolo li incontriamo tutti: gli interi, i decimali, il denaro e le frazioni.

Interi e decimali

Un intero è un numero senza virgola: 42, -7, 0. Un decimale ha la virgola — anzi, in Leo, il punto: si scrive 3.14, non 3,14. È una regola che vale in quasi tutti i linguaggi di programmazione, e ci si abitua in fretta: la virgola, in Leo, serve a separare le cose (gli elementi di una lista, gli argomenti di una funzione), mai a scrivere i decimali.

💡 L'idea — Contare o misurare

Gli interi sono come contare oggetti: tre mele sono tre mele, un numero netto, senza sfumature. I decimali sono come misurare con un righello: dici «2,7 centimetri», ma sotto la tacca c'è sempre un pelo in più o in meno che non riesci a leggere. Per questo gli interi sono esatti per natura, mentre i decimali portano con sé, quasi sempre, una piccola approssimazione — come vedremo tra poco con i soldi.

Le operazioni sono quelle che conosci dalla scuola:

Leo
scrivi(7 + 2)
scrivi(7 - 2)
scrivi(7 * 2)
scrivi(7 / 2)
scrivi(7 // 2)
scrivi(7 % 3)
scrivi(2 ^ 10)
Risultato
9
5
14
3.5
3
1
1024

Tre di queste meritano una parola. La divisione / dà sempre un decimale, anche quando il conto tornerebbe intero: 7 / 2 è 3.5, e 10 / 2 sarebbe 5.0. Quando invece vuoi solo il quoziente intero (quante volte ci sta, senza resto) usi la doppia barra //: 7 // 2 è 3. Il resto di quella divisione lo dà %: 7 % 3 è 1 (sette diviso tre fa due, con resto uno). La potenza si scrive con l'accento circonflesso ^: 2 ^ 10 è 1024.

Gli interi di Leo non hanno limiti di grandezza. Puoi calcolare numeri enormi senza che «traboccino», cosa che in molti linguaggi causa risultati sbagliati:

Leo
scrivi(1_000_000 + 1)
scrivi(2 ^ 100)
Risultato
1000001
1267650600228229401496703205376

(Hai notato il trattino basso in 1_000_000? Serve solo a te, per leggere meglio le cifre: Leo lo ignora. Puoi scrivere 1_000_000 invece di 1000000.)

Qualche funzione utile

Alcune operazioni comuni sono funzioni già pronte, sempre disponibili:

Leo
variabile pi = 3.14159
scrivi(arrotonda(pi, 2))
scrivi(arrotonda(2.5))
scrivi(radice(16))
scrivi(assoluto(-7))
scrivi(minimo([3, 9, 4]))
scrivi(massimo([3, 9, 4]))
scrivi(somma([10, 20, 30]))
Risultato
3.14
3
4.0
7
3
9
60

arrotonda(numero, cifre) arrotonda a quante cifre decimali vuoi; senza indicare le cifre dà un intero, e arrotonda le metà lontano da zero (arrotonda(2.5) è 3, come ti hanno insegnato a scuola, non come fa di nascosto qualche altro linguaggio). radice è la radice quadrata, assoluto toglie il segno, minimo e massimo scelgono tra i valori di una lista, somma li addiziona tutti. Nel Capitolo 15, parlando della libreria, ne incontreremo molte altre, su tutte la statistica (media, mediana, deviazione).

Scrivere i numeri come si deve

Un conto è calcolare 1234.5, un altro è mostrarlo a una persona. Un prezzo si scrive con due decimali; un numero grande si legge meglio con i punti delle migliaia. Dentro un testo, dopo l'espressione metti i due punti e un formato:

Leo
variabile prezzo = 1234.5
scrivi "{prezzo:2}"
scrivi "{1234567:migliaia}"
scrivi "{prezzo:migliaia 2}"
Risultato
1234.50
1.234.567
1.234,50

{prezzo:2} forza due cifre decimali (1234.50, con lo zero finale che un prezzo deve avere). {n:migliaia} mette i punti delle migliaia all'italiana. {prezzo:migliaia 2} fa entrambe le cose, ed è il formato perfetto per gli importi: 1.234,50, con il punto per le migliaia e la virgola per i decimali, esattamente come su una fattura. Questa formattazione vale solo per i numeri; se sbagli il formato, Leo te lo dice e ti propone quello giusto.

Il denaro: i centesimi non si perdono

Qui arriviamo a una delle idee più belle di Leo. I numeri decimali del computer — quelli che hai visto sopra — seguono uno standard tecnico (si chiama IEEE-754) che è velocissimo ma non è esatto con i decimali. Suona astratto? Guarda:

Leo
scrivi(0.1 + 0.2)
Risultato
0.30000000000000004

Dieci centesimi più venti centesimi dovrebbero fare trenta centesimi tondi, e invece spunta quella coda di zeri e un 4 finale. Per i calcoli scientifici è irrilevante; per i soldi è inaccettabile. Per questo Leo ha un tipo pensato apposta per il denaro, soldi, che tiene i centesimi esatti:

Leo
variabile conto = soldi("10.00")
variabile spesa = soldi("3.50")
scrivi(conto.meno(spesa))
scrivi(soldi("0.10").piu(soldi("0.20")))
Risultato
6,50 €
0,30 €

Niente code di zeri: trenta centesimi sono trenta centesimi. Nota due cose. Si crea un importo da un testo (soldi("10.00")), così non si eredita l'imprecisione dei decimali fin dalla nascita; e le operazioni si scrivono a parole — .piu(...), .meno(...) — perché non stiamo facendo aritmetica qualunque, stiamo facendo i conti della serva, e vogliamo che siano giusti al centesimo. Il risultato si stampa già all'italiana, con la virgola e il simbolo dell'euro.

🦁 Curiosità — Quando un'unità sbagliata costa una sonda

Nel 1999 la NASA perse la sonda Mars Climate Orbiter, un progetto da circa 327 milioni di dollari, proprio mentre si avvicinava a Marte. La causa fu banale e amara: un gruppo di lavoro aveva usato le unità di misura anglosassoni e un altro il sistema metrico, e nessuno dei due convertì i numeri. I conti erano «giusti», ma nelle unità sbagliate. È il promemoria perfetto del perché, con i numeri, contano tanto il tipo e l'unità quanto il valore.

C'è anche un tocco di eleganza tutto italiano: euro_in_lettere scrive un importo in parole, come sugli assegni.

Leo
scrivi(euro_in_lettere(19.90))
Risultato
diciannove euro e novanta centesimi

Le frazioni: niente approssimazioni

Un terzo più un sesto fa esattamente un mezzo. Prova a dirlo con i decimali e otterrai 0.333... più 0.166..., con tutte le approssimazioni del caso. Leo ha il tipo frazione, che tiene i numeri razionali esatti e li semplifica da solo:

Leo
variabile meta = frazione(1, 2)
variabile terzo = frazione(1, 3)
scrivi(meta.piu(terzo))
scrivi(meta.per(terzo))
scrivi(frazione(2, 4))
Risultato
5/6
1/6
1/2

Un mezzo più un terzo fa cinque sesti, esatto; un mezzo per un terzo fa un sesto; e frazione(2, 4) si semplifica da sé in 1/2. È il tipo giusto per la matematica, la didattica e ogni volta che un'approssimazione sarebbe un tradimento.

Trasformare un tipo nell'altro

Leo non converte mai i tipi di nascosto: "3" + 4 è un errore, non 7 né "34". Questa severità ti protegge dai bug, ma a volte una conversione la vuoi davvero — per esempio quando chiedi ti ha dato un testo e tu vuoi un numero. Le conversioni si fanno a mano, con funzioni dal nome trasparente:

Leo
variabile testo_numero = "42"
variabile n = intero(testo_numero)
scrivi(n + 1)
scrivi(decimale("3.5"))
scrivi(testo(3.5))
Risultato
43
3.5
3.5

intero(...) trasforma un testo in un numero intero; decimale(...) in un decimale; testo(...) fa il contrario, trasforma qualunque valore nel suo testo. Se la conversione non ha senso — intero("ciao") — ottieni un ErroreValore chiaro, non un risultato a caso.

Prova tu

  1. Chiedi all'utente due numeri (ricorda: chiedi dà un testo, trasformalo con intero) e stampa somma, differenza, prodotto e quoziente.
  2. Scrivi un piccolo «conto del ristorante»: parti da soldi("0.00"), aggiungi tre o quattro voci con .piu(...), poi stampa il totale e lo stesso totale in lettere con euro_in_lettere.
  3. Verifica con le frazioni che 1/2 + 1/3 + 1/6 fa esattamente 1. Poi prova lo stesso conto con i decimali (0.5 + 0.333... ) e osserva la differenza.