Skip to content
This repository has been archived by the owner on Jun 16, 2023. It is now read-only.

Commit

Permalink
fine lezione 11
Browse files Browse the repository at this point in the history
  • Loading branch information
mc-cat-tty committed Nov 2, 2021
1 parent 60a129b commit 138f54f
Show file tree
Hide file tree
Showing 9 changed files with 217 additions and 0 deletions.
Binary file added .12_float_double.md.swp
Binary file not shown.
86 changes: 86 additions & 0 deletions 12_float_double.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Float and double
Numeri con componenti frazionari. Comunemente chiamati reali, ma nella realtà

## Notazione scientifica
`2.4e2` => 2.4 * 10^2
Funziona sia per gli esponenti negativi che per quelli positivi

## Letterali reali
Per inidcare che una costante lettereale è da inerpretare come reale, è necessario porre un punto alla fine di essa, indipendentemetne dalla presenza della parte decimale. `102.`

## Downcast e upcast
Downcast -> perdita di informazioni
Upcast -> eg: da int a float

## Stampa numeri reali
Il numero stampato su stdout da cout potrebbe non coincidere con il numero presente in memoria. I numeri reali vengono stampati con un ragionevole numero di cifre dopo la virgola.

## Rappresentazione in memoria
- virgola fissa
- virgola mobile: ho un limite massimo di cifre significative che posso rappresentare e sposto la virgola in base al valore della parte decimale

### Componenti in virgola mobile
- segno
- mantissa (_significand_): cifre del numero (intere e decimali)
- esponente in base 10: indica la posizione della virgola

Il numero si immagina nella forma: mantissa\*10^esponente

La posizione iniziale della virgola si trova al terzo posto a partire da destra.

Esponente:
- positivo: spostamento della virgola di n cifre verso destra
- negativo: spostamento virgola verso sinistra

## Float vs double
Entrambi vengono rappresentati in virgola mobile
Sottoinsieme dei numeri reali -> sono un'approssimazione sia come range di valori rappresentabili che come numero di cifre contenuto nella mantissa

I numeri periodici vengono approssimati

## Manipolatore `setprecision`
=> setta un numero massimo di cifre per un numero in virgola mobile
`#include <iomanip>`
L'istruzione `setprecision(<cifre-dopo-la-virgola>)` ha un effetto permanente

TODO: vedi divisione_reale.cpp

Approssimazione migliore del tipo double: 16esima cifra dopo la virgola

## Standard IEEE754
=> definisce la rappresentazione tipica di float e double.

Memorizzazione esponente: si potrebbe utilizzare il complemento a due, ma è stao deciso di usare un offset => esponente = _num-offset_ -> viene memorizzato num

La prima cifra della mantissa deve sempre essere diversa da zero -> siamo in base 2, quindi è uguale a 1. Questo permette di evitare la memorizzazione degli zeri anteposti al numero.
Siamo arrivati ad un numero nella forma 1.xxxxx -> non è necessario memorizzare l'1, basta xxxxx

Valore minimo: -offset se num=0
Valore massimo: tutti i bit a 1
Zero: se num=offset

TODO: vedi ieee754 floating point converter

## Conversion
Per ogni cifra binaria a destra della virgola il valore decimale viene dimezzato

## Precisione
=> La precisione P di un dato tipo di dato numerico viene definita come il numero massimo di cifre (in base b) tali che, qualsiasi numero rappresentato su P cifre, è rappresentabile in modo esatto dal tipo di dato.

Tipicamente il float (4 byte) hanno un precisione di 6 cifre decimali, mentre il double (8 byte) ne ha 15. Inoltre esistono i long double, che occupano 10 byte in memoria.

=> la precisione è data dal numero di bit (in base 2) memorizzabili nella mantissa + 1 (bit non memorizzato). Eg. la precisione in base 2 degli interi è 31 (ricorda bit segno)

## Memorizzare numeri > 1 in float/double
È possibile memorizzare numeri maggiori di 1 utilizzando l'esponente, ma non possiamo essere sicuri che le cife dopo la P-esima siano corrette (assimilate a zeri)
=> questo problema prende il nome di *troncamento* -> necessario per memorizzazione

## Memorizzazione di numeri non scrivibili come somma degli inversi delle potenze di 2
=> numeri come 0.1 non possono essere rappresentati in modo corretto sulla macchina

## Operazioni miste
=> In un'operazione ad operatori misti basta che uno sia ti tipo reale che il risultato diventa reale
-> upcast (il compilatore "alza" il tipo di dato)

## Rappresentazione dello zero
La mantissa, per definizione ha la prima cifra diversa da zero, quindi 0 non sarebbe rappresentabile -> se tutti i bit sono esattamente a zero, il numero complessivo è considerato come zero.
Binary file added esercitazioni/.ascensore.cpp.swp
Binary file not shown.
49 changes: 49 additions & 0 deletions esercitazioni/ascensore.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Esercizio "ascensore sgravata impazzita"
*/

#include <iostream>
#include <cmath>

using namespace std;

enum direzione {su, giu};

double singolo_impulso(double, direzione);

int main() {
// struttura dati
double pos = 0.; // posizione iniziale (+20 metri dal suolo)

int ch;
int n; // numero spostamenti

const double epsilon = 1e-7;

do {
cout << pos << endl;
// PROBLEMA: lo zero non viene rappresentato in modo preciso;
if ((pos > 1.0-epsilon && pos < 1.0+epsilon)) // PERICOLO: pos potrebbe non essere esattamente a 1. Non usare l'uguaglianza pura, perchè viene fatto un controllo bit per bit tra i numeri.
cout << "Non sicuro staccare le funi" << endl;
else
cout << "Sicuro staccare le funi" << endl;
cout << endl;

cout << "Movimento: ";
cin >> n;

if (n>0 && pos+(n/10) >= 20)
pos = 20;
if (n<0 && pos-(n/10) <= -20)
pos = -20;
else
for (int i=0; i<abs(n); i++)
pos = singolo_impulso(pos, n > 0 ? su : giu);

} while (n != 0);
return 0;
}

double singolo_impulso(double n, direzione dir) {
return n + (dir == su ? 0.1 : -0.1);
}
9 changes: 9 additions & 0 deletions esercitazioni/div_reale2.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include <iostream>
using namespace std;

int main() {
int a, b;
cin >> a >> b;
cout << a/b << endl;
cout << static_cast<float>(a)/b << endl;
}
11 changes: 11 additions & 0 deletions esercitazioni/divisione_reale.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include <iostream>
#include <iomanip>

using namespace std;

int main() {
float a=2, b=3;
double x=2, y=3;
cout << setprecision(20) << a/b << endl;
cout << x/y << endl;
}
11 changes: 11 additions & 0 deletions esercitazioni/reale_int.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include <iostream>
using namespace std;

int main() {
float a;
int b;
cin >> a;
b = static_cast<int>(a);
cout << a << endl;
cout << b << endl;
}
Binary file added esercitazioni/rsa/a.out
Binary file not shown.
51 changes: 51 additions & 0 deletions ù
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Float and double
Numeri con componenti frazionari. Comunemente chiamati reali, ma nella realtà

## Notazione scientifica
`2.4e2` => 2.4 * 10^2
Funziona sia per gli esponenti negativi che per quelli positivi

## Letterali reali
Per inidcare che una costante lettereale è da inerpretare come reale, è necessario porre un punto alla fine di essa, indipendentemetne dalla presenza della parte decimale. `102.`

## Downcast e upcast
Downcast -> perdita di informazioni
Upcast -> eg: da int a float

## Stampa numeri reali
Il numero stampato su stdout da cout potrebbe non coincidere con il numero presente in memoria. I numeri reali vengono stampati con un ragionevole numero di cifre dopo la virgola.

## Rappresentazione in memoria
- virgola fissa
- virgola mobile: ho un limite massimo di cifre significative che posso rappresentare e sposto la virgola in base al valore della parte decimale

### Componenti in virgola mobile
- segno
- mantissa (_significand_): cifre del numero (intere e decimali)
- esponente in base 10: indica la posizione della virgola

Il numero si immagina nella forma: mantissa\*10^esponente

La posizione iniziale della virgola si trova al terzo posto a partire da destra.

Esponente:
- positivo: spostamento della virgola di n cifre verso destra
- negativo: spostamento virgola verso sinistra

## Float vs double
Entrambi vengono rappresentati in virgola mobile
Sottoinsieme dei numeri reali -> sono un'approssimazione sia come range di valori rappresentabili che come numero di cifre contenuto nella mantissa

I numeri periodici vengono approssimati

## Manipolatore `setprecision`
=> setta un numero massimo di cifre per un numero in virgola mobile
`#include <iomanip>`
L'istruzione `setprecision(<cifre-dopo-la-virgola>)` ha un effetto permanente

TODO: vedi divisione_reale.cpp

Approssimazione migliore del tipo double: 16esima cifra dopo la virgola

## Standard IEEE754
=> definisce la rappresentazione tipica di float e double.

0 comments on commit 138f54f

Please sign in to comment.