Basi 3 - numeri reali
Scarica zip esercizi
REQUISITI:
Letto Basi 2 - booleani
Numeri reali
Python salva i numeri reali (numeri in virgola mobile) in 64 bit di informazione divisi in segno, esponente e mantissa. Vediamo un esempio:
[2]:
3.14
[2]:
3.14
[3]:
type(3.14)
[3]:
float
ATTENZIONE: bisogna usare il punto invece della virgola!
Quindi scriverai 3.14
invece di 3,14
Fai molta attenzione quando copi numeri da documenti in italiano, potrebbero contenere insidiose virgole !
Notazione scientifica
Quando i numeri sono molto grandi o molto piccoli, per evitare di scrivere troppi zero conviene usare la notazione scientitifica con la e come \(xen\), che moltiplica il numero x per \(10^n\)
Con questa notazione, in memoria vengono messe solo le cifre più significative ( la mantissa ) e l’esponente, evitando quindi di sprecare spazio.
[4]:
75e1
[4]:
750.0
[5]:
75e2
[5]:
7500.0
[6]:
75e3
[6]:
75000.0
[7]:
75e123
[7]:
7.5e+124
[8]:
75e0
[8]:
75.0
[9]:
75e-1
[9]:
7.5
[10]:
75e-2
[10]:
0.75
[11]:
75e-123
[11]:
7.5e-122
DOMANDA: Guarda le seguenti espressioni, e cerca di indovinare quale risultato producono (o se danno errore):
print(1.000.000)
print(3,000,000.000)
print(2000000.000)
print(2000000.0)
print(0.000.123)
print(0.123)
print(0.-123)
print(3e0)
print(3.0e0)
print(7e-1)
print(3.0e2)
print(3.0e-2)
print(3.0-e2)
print(4e2-4e1)
Numeri troppo grandi o troppo piccoli
A volte i calcoli su numeri estremamente piccoli o enormi possono produrre come risultato math.nan
(Not a Number) o math.inf
. Per il momento li menzioniamo e basta, trovi una discussione dettagliata nel foglio su Numpy
Esercizio - cerchio
Calcola l’area del cerchio al centro di un pallone da calcio (raggio = 9.15m), ricordandoti che \(area= pi*r^2\) (come operatore per la potenza, usa **
):
Il tuo codice dovrebbe stampare come risultato 263.02199094102605
[37]:
Nota che le parentesi intorno al r**2
non sono necessarie perchè l’operatore **
ha la precedenza, ma possono aiutare la leggibilità del codice.
Ricordiamo qua la precedenza degli operatori:
Operatore |
Descrizione |
---|---|
|
Potenza (massima precedenza) |
|
Più e meno unari |
|
Moltiplicazione, divisione, divisione intera, modulo |
|
Addizione e sottrazione |
|
Operatori di comparazione |
|
Operatori di uguaglianza |
|
Operatori logici (minima precedenza) |
Esercizio - Il campo da golf
Il giardiniere Jobe è diventato così bravo che il dottor Angelo decide di promuoverlo a curatore del campo da golf dove è solito trascorrere i weekend. Ma una nuova sfida lo attende: al campo Jobe deve radere perfettamente il green, cioè l’area circolare di raggio r
che comprende la buca. La spia sul tagliaerbe di Jobe si deve accendere quando è posizionato sul verde chiaro: scrivi un espressione che date due coordinate x,y
produce True
quando il tagliaerbe è sul verde chiaro, e
False
altrimenti. Al solo scopo di darti dei riferimenti visuali, questa volta sul campo sono disposte anche delle palline con delle lettere.
NOTA: questa volta l’origine è al centro del quadrato
NON usare il comando
if
SUGGERIMENTO: ti ricordi come si calcola la distanza tra due punti? Avrai bisogno della radice quadrata
math.sqrt
…
[13]:
import math
r = 50
x,y = 35,20 # A: True
#x,y = 45,-40 # B: False
#x,y = 10,-40 # C: True
#x,y = -41,-46 # D: False
#x,y = -30,-10 # E: True
#x,y = -35,35 # F: True
#x,y = -37,37 # G: False
# scrivi qui
[13]:
True
Esercizio - frazionamento
Scrivi del codice per calcolare il valore della seguente formula per x = 0.000003
, dovresti ottenere 2.753278226511882
[14]:
x = 0.000003
# scrivi qui
[14]:
2.753278226511882
Esercizio - sommatoria
Scrivi del codice per calcolare il valore della seguente espressione (non usare cicli, scrivi per esteso tutto i calcoli), dovresti ottenere 20.53333333333333
[15]:
# scrivi qui
[15]:
20.53333333333333
Reali - conversione
Se vogliamo convertire un reale ad un intero, abbiamo a disposizione diversi modi:
Funzione |
Descrizione |
Simbolo matematico |
Risultato |
---|---|---|---|
|
arrotonda x all’intero inferiore |
\[\lfloor{8.7}\rfloor\]
|
8 |
|
arrotonda x all’intero inferiore |
\[\lfloor{8.7}\rfloor\]
|
8 |
|
arrotonda x all’intero superiore |
\[\lceil{5.3}\rceil\]
|
6 |
|
arrotonda x all’intero più vicino |
\[\lfloor{2.49}\rceil\]
|
2 |
\[\lfloor{2.51}\rceil\]
|
3 |
DOMANDA: Guarda le espressioni seguenti, e per ciascuna cerca di indovinare quale risultato produce (o se da errore).
math.floor(2.3)
math.floor(-2.3)
round(3.49)
round(3.51)
round(-3.49)
round(-3.51)
math.ceil(8.1)
math.ceil(-8.1)
DOMANDA: Dato un qualsiasi float x
, la seguente formula è :
math.floor(math.ceil(x)) == math.ceil(math.floor(x))
sempre
True
sempre
False
a volte
True
e a volteFalse
(fornire esempi)
DOMANDA: Dato un qualsiasi float x
, la seguente formula è :
math.floor(x) == -math.ceil(-x)
sempre
True
sempre
False
a volte
True
e a volteFalse
(fornire esempi)
Esercizio - tonificante
Gli studi eccessivi ti hanno portato a cercare su internet ricette di bevande energetiche. Fortunatamente, una guru della nutrizione ha appena postato sul suo canale Instagram @BeviCheTiFaBene la ricetta di un frappè portentoso:
Versare in un contenitore 2 decilitri di spremuta di kiwi, 4 decilitri di salsa di soia, e 3 decilitri di shampoo al karitè bio. Miscelare vigorosamente e poi versare metà del composto in un bicchiere. Rabboccare il bicchiere fino al decilitro intero superiore. Tracannare avidamente.
Corri a comprare gli ingredienti, e ti appresti a miscelarli. Hai a disposizione un misurino in cui travasi i preziosi fluidi, ad uno ad uno. Nell’effettuare il travaso, versi sempre un po’ più del necessario (ma mai più di 1 decilitro), e ad ogni ingrediente elimini poi l’eccesso.
NON usare sottrazioni, prova ad usare solo gli operatori per gli arrotondamenti
Esempio:
Dati
kiwi = 2.4
soia = 4.8
shampoo = 3.1
misurino = 0.0
mixer = 0
bicchiere = 0.0
Il tuo codice deve stampare:
Verso nel misurino 2.4 dl di kiwi, tolgo eccesso fino a tenere 2 dl
Travaso nel mixer, adesso contiene 2 dl
Verso nel misurino 4.8 dl di soia, tolgo eccesso fino a tenere 4 dl
Travaso nel mixer, adesso contiene 6 dl
Verso nel misurino 3.1 dl di shampoo, tolgo eccesso fino a tenere 3 dl
Travaso nel mixer, adesso contiene 9 dl
Verso metà della miscela ( 4.5 dl ) nel bicchiere
Rabbocco il bicchiere fino al decilitro intero superiore, adesso contiene 5 dl
[16]:
kiwi = 2.4
soia = 4.8
shampoo = 3.1
misurino = 0.0
mixer = 0.0
bicchiere = 0.0
# scrivi qui
Verso nel misurino 2.4 dl di kiwi, tolgo eccesso fino a tenere 2 dl
Travaso nel mixer, adesso contiene 2.0 dl
Verso nel misurino 4.8 dl di soia, tolgo eccesso fino a tenere 4 dl
Travaso nel mixer, adesso contiene 6.0 dl
Verso nel misurino 3.1 dl di shampoo, tolgo eccesso fino a tenere 3 dl
Travaso nel mixer, adesso contiene 9.0 dl
Verso metà della miscela ( 4.5 dl ) nel bicchiere
Rabbocco il bicchiere fino al decilitro intero superiore, adesso contiene: 5 dl
Esercizio - arrotondamente
Scrivi del codice per calcolare il valore della seguente formula per x = -5.51
, dovresti ottenere 41
[17]:
import math
x = -5.51 # 41
#x = -5.49 # 30
# scrivi qui
[17]:
41
Reali - uguaglianza
ATTENZIONE: Ciò che segue vale per *tutti* i linguaggi di programmazione!
Alcuni risultati ti parranno curiosi ma è il modo in cui la maggior parte dei processori (CPU) opera, indipendentemente da Python.
Quando si effettuano calcoli con i numeri in virgola mobile, il processore può commettere degli errori di arrotondamento dovuto ai limiti della rappresentazione interna. Sotto il cofano i numeri float vengono memorizzati in una sequenza in codice binario di 64 bit, secondo lo standard IEEE-754 floating point arithmetic : questo impone un limite fisico alla precisione dei numeri, e a volte possono anche capitare sorpese dovute alla conversione da decimale a binario. Per esempio, proviamo a
stampare 4.1
:
[18]:
print(4.1)
4.1
Per nostra convenienza Python ci mostra 4.1
, ma in realtà nella memoria del processore è finito un numero diverso ! Quale? Per scoprire cosa nasconde, con format
possiamo esplicitamente formattare il numero con lo specificatore di formato f
usando per esempio 55
cifre di precisione:
[19]:
format(4.1, '.55f')
[19]:
'4.0999999999999996447286321199499070644378662109375000000'
Possiamo quindi chiederci quale potrà essere il risultato di un calcolo:
[20]:
print(7.9 - 3.8)
4.1000000000000005
Notiamo che il risultato è ancora diverso da quello atteso ! Indagando meglio, notiamo che Python non ci sta nemmeno mostrando tutte le cifre:
[21]:
format(7.9 - 3.8, '.55f')
[21]:
'4.1000000000000005329070518200751394033432006835937500000'
E se volessimo sapere se due calcoli coi float producono lo ‘stesso’ risultato?
ATTENZIONE: EVITA IL ==
CON I FLOAT!
Per capire se il risultato tra due calcoli con i float è uguale, NON puoi usare l’operatore ==
:
[22]:
7.9 - 3.8 == 4.1 # GUAI IN VISTA !
[22]:
False
Invece, devi preferire alternative che valutano se un numero float è vicino ad un altro, come per esempio la comoda funzione math.isclose:
[23]:
import math
math.isclose(7.9 - 3.8, 4.1) # MOLTO MEGLIO
[23]:
True
Di default math.isclose
usa una precisione di 1e-09
ma volendo, a math.isclose
puoi anche passare un limite di tolleranza entro la quale deve essere la differenza tra i due numeri affinchè siano considerati uguali:
[24]:
math.isclose(7.9 - 3.8, 4.1, abs_tol=0.000001)
[24]:
True
DOMANDA: Possiamo rappresentare perfettamente il numero \(\sqrt{2}\) in un float
?
DOMANDA: Quali di queste tre espressioni di codice danno lo stesso risultato?
import math
print('a)', math.sqrt(3)**2 == 3.0)
print('b)', abs(math.sqrt(3)**2 - 3.0) < 0.0000001)
print('c)', math.isclose(math.sqrt(3)**2, 3.0, abs_tol=0.0000001))
Esercizio - quadratica
Scrivi del codice che calcola gli zero dell’equazione \(ax^2-b = 0\)
Mostra i numeri con 20 cifre di precisione
Alla fine controlla che sostituendo il valore ottenuto di
x
nell’equazione si ottenga effettivamente zero.
Esempio - dati:
a = 11.0
b = 3.3
dopo il tuo codice deve stampare:
11.0 * x**2 - 3.3 = 0 per x1 = 0.54772255750516607442
11.0 * x**2 - 3.3 = 0 per x2 = -0.54772255750516607442
0.54772255750516607442 è una soluzione? True
-0.54772255750516607442 è una soluzione? True
[25]:
a = 11.0
b = 3.3
# scrivi qui
Esercizio - alla moda
Stai già pensando alle prossime vacanze, ma c’è un problema: dove vai, se un selfie-stick non ce l’hai? Non puoi partire con questo grave turbamento: per uniformarti al fenomeno di massa devi comprare lo stick più simile agli altri. Conduci quindi prima un’indagine statistica tra turisti malati di selfie-stick con l’obiettivo di scoprire i brand più frequenti, in altre parole, la moda delle frequenze. Ottieni questi risultati:
[26]:
b1,b2,b3,b4,b5 = 'TroppiLike', 'ErMejo United', 'Perditempo SpA', 'Vanità 3.0','TronistiPerCaso' # brand
f1,f2,f3,f4,f5 = 0.25, 0.3, 0.1, 0.05, 0.3 # frequenze (in percentuale)
Desumiamo quindi che le masse prediligono i selfie-stick dei brand 'ErMejo United'
e 'TronistiPerCaso'
, entrambi a parimerito con un 30% di turisti ciascuno. Scrivi quindi del codice che stampa questo risultato:
TroppiLike è il più frequente? False ( 25.0 % )
ErMejo United è il più frequente? True ( 30.0 % )
Perditempo Inc è il più frequente? False ( 10.0 % )
Vanità 3.0 è il più frequente? False ( 5.0 % )
TronistiPerCaso è il più frequente? True ( 30.0 % )
ATTENZIONE: il tuo codice deve funzionare con QUALUNQUE serie di variabili !!
[27]:
b1,b2,b3,b4,b5 = 'TroppiLike', 'ErMejo United', 'Perditempo Inc', 'Vanità 3.0','TronistiPerCaso' # brand
f1,f2,f3,f4,f5 = 0.25, 0.3, 0.1, 0.05, 0.3 # frequenze (in percentuale) False True False False True
# OCCHIO, sembrano uguali ma deve funzionare anche con queste ;-)
#f1,f2,f3,f4,f5 = 0.25, 0.3, 0.1, 0.05, 0.1 + 0.2 # False True False False True
# scrivi qui
Numeri decimali
Per moltissime applicazioni i float
sono sufficienti, avendo coscienza dei loro limiti di rappresentazione e uguaglianza. Se proprio hai bisogno di maggiore precisione e/o prevedibilità, Python offre un tipo numerico apposito chiamato Decimal
, che permette una precisione arbitraria. Per usarlo, devi prima importarlo dalla libreria decimal
:
[28]:
from decimal import Decimal
Possiamo creare un Decimal
a partire da una stringa:
[29]:
Decimal('4.1')
[29]:
Decimal('4.1')
ATTENZIONE: se crei un Decimal a partire da una costante, indicala come stringa!
Se gli passi un float
rischi di perdere l’utilità dei Decimal:
[30]:
Decimal(4.1) # così mi ritrovo coi problemi dei float ...
[30]:
Decimal('4.0999999999999996447286321199499070644378662109375')
Operazioni tra Decimal
producono altri Decimal
:
[31]:
Decimal('7.9') - Decimal('3.8')
[31]:
Decimal('4.1')
Questa volta, possiamo tranquillamente usare l’operatore di uguaglianza e ottenere il risultato atteso:
[32]:
Decimal('4.1') == Decimal('7.9') - Decimal('3.8')
[32]:
True
Sono anche supportate alcune funzioni matematiche, e spesso si comportano in modo più predicibile (nota che non stiamo usando math.sqrt
):
[33]:
Decimal('2').sqrt()
[33]:
Decimal('1.414213562373095048801688724')
Ricordati comunque che la memoria del computer è finita!
I Decimal non possono essere la panacea per tutti i mali: per es, \(\sqrt{2}\) non ci starà mai completamente nella memoria di nessun computer ! Possiamo verificare le limitazioni elevando al quadrato il risultato:
[34]:
Decimal('2').sqrt()**Decimal('2')
[34]:
Decimal('1.999999999999999999999999999')
L’unica cosa che possiamo avere in più coi Decimal è un maggiore numero di cifre per rappresentarli, che volendo possiamo aumentare a piacere finchè non esauriamo la memoria del nostro pc. In questo libro non parleremo oltre dei Decimal perchè tipicamente servono solo per applicazioni specifiche, per esempio, se devi fare calcoli finanziari vorrai probabilmente usare cifre esatte !
Prosegui
Continua con le challenges