Newsgroup: it.comp.hardware.cpu
Titolo: Variabili in virgola mobile

Porto qui una disputa nata su altro NG dove risulta fuori tema..
Parliamo delle variabili in virgola mobile offerte al programmatore in
un generico linguaggio.
Posizione A
Sono i linguaggi di programmazione che definiscono i tipi di dati che
vogliono usare. Il calcolatore funziona con aritmetica intera.
Posizione B
I linguaggi di programmazione possono utilizzare variabili a virgola
mobile che i calcolatori odierni trattano come tali, seguendo, per
esempio, lo standard IEEE 754 che definisce come sono rappresentati i
valori in floating point e quindi i limiti relativi alla loro
precisione.
Cosa c'è di esatto e di sbagliato nelle due posizioni A e B?
Grazie.

Cosa c'� di esatto e di sbagliato nelle due posizioni A e B?
Posizione A
Non � vero che il calcolatore funziona con aritmetica intera, altrimenti chi 
sostiene questa tesi dovrebbe spiegarci a che servono le FPU 
http://it.wikipedia.org/wiki/Unit%C3%A0_di_calcolo_in_virgola_mobile
Posizione B
Nulla da eccepire 

 Grazie.
Come giï¿œ detto la posizione sbagliata ï¿œ la A... le cpu lavorano anche 
in virgola mobile giï¿œ da 25 anni come minimo.

 precisione.
Vero, e' quello che generalmente accade ed e' solitamente sufficiente.
Sei pero' legato ai limiti di implementazione dello specifico processore,
per cui in casi particolari il compilatore o il programmatore dovranno
ricorrere all'aritmetica intera per sopperire a questi limiti o soddisfare
esigenze specifiche.
In conclusione, con i linguaggi/compilatori e CPU odierni la posizione
generalmente piu' corretta e' la B, ma anche la A potrebbe essere corretta
a fronte di particolari esigenze di precisione o di utilizzo di CPU senza
FPU.
Ciao,
  Luca

Luca MaBAT, eXeS, Lorenz,
Grazie mille. Condivido tutto quanto avete scritto.
Dovevo essere neutro per correttezza, questa sotto è la mia posizione.
___________________________________________________________
Non hai ancora capito che tutti gli errori contabili di cui stiamo
parlando derivano dal seguire uno standard di rappresentazione di
queste varialbili? Pensi che dipenda tutto dalle capacità di
programmazione? Che libertà ho di agire sui registri interi della CPU
quando uso la calcolatrice, quando uso Excel o quando uso una
variabile in doppia precisione in un programma?
Se poi servissero grandi precisioni non è neppure necessario, come
sostiene il mio antagonista, agire sui registri della CPU scrivendo un
programma di avvio del computer e un personale "sistema operativo". Mi
basterebbe definire numeri decimali con cifre a volontà su vettori di
byte e implementare in codice le operazioni matematiche che mi servono.

 ha scritto nel messaggio 
news:6b218e42-59ff-4d64...@j20g2000vbp.googlegroups.com...
Luca MaBAT, eXeS, Lorenz,
Grazie mille. Condivido tutto quanto avete scritto.
Dovevo essere neutro per correttezza, questa sotto � la mia posizione.
___________________________________________________________
Poich� vedo che stai parlando di errori contabili, la prassi vuole che in 
tali casi si debba usare una numerazione a virgola fissa anzich� una a 
virgola mobile, questo in quanto il secondo tipo di numerazione presenta dei 
limiti di precisione che in ambito finanziario non sono tollerabili.
Ad esempio il risultato di questa operazione
float f = 0.00000001f;
System.out.println(1f + f);
usando una numerazione in virgola mobile �  1.0 e non 1.00000001
In Java ad esempio si pu� usare questa soluzione, la classe BigDecimal nasce 
appunto per ovviare alle limitazioni del numeri a virgola mobile
BigDecimal b1 = new BigDecimal("1");
BigDecimal b2 = new BigDecimal("0.00000001").;
System.out.println(b1.add(b2));
e il risultato � quello atteso.
Ma nulla vieta ad esempio se l'operazione � di somma o moltiplicazione, una 
volta stabilito che il numero sar� composto sempre da n cifre di cui m 
decimali, di rappresentare il numero decimale con un intero a n cifre, e 
solo in fase di visualizzazione piazzare la virgola a posizione n-m
Il caso precedente ad esempio avremmo potuto risolverlo in questo modo 
assumendo n=9 e m=8
int i1=100000000;
int i2=000000001;
String rStr=Integer.toString(i1 + i2);
System.out.println(rStr.substring(0,1)+"." + rStr.substring(1));

 limiti di precisione che in ambito finanziario non sono tollerabili.
Effettivamente avevamo discusso di propagazione errori, ma non in
ambito contabile. Da quanto ne so, in questi casi si operano
arrotondamenti ben documentati nelle varie fasi del calcolo. Così
avviene, per esempio, nelle dichiarazioni dei redditi.
Abbiamo invece esaminato cosa succede in Excel o Calc (non vedo
differenze) quando si opera ai limiti della precisione offerta (doppia
precisione in binario, 15 cifre in decimale). L'aspetto strano è io e
il mio interlocutore otteniamo risultati diversi a parità di
operazione, che non capisco a cosa siano dovuti.
Calcolando in Excel (2^(1/1024))^1024 si ottiene una cifra decimale
"sporca".
2,00000000000002000000E+00 (il 2 al 14° decimale è la cifre sporca).
Con con semplice operazione 1/3-0,33333333333333 si ottengono ben 12
cifre "sporche", ovvero 3,33066907387547000000E-15 (066907387547 sono
le cifre sporche).
A mio parere ci dovrebbe essere messo a disposizione un formato che
evidenzia quali sono le cifre ancora "buone", ovvero significative
(dedotte da un calcolo di propagazione degli errori).
Per esempio, con questo formato i due risultati sarebbero
rappresentati rispettivamente come:
2,0000000000000E+00
3,33E-15

 byte e implementare in codice le operazioni matematiche che mi servono.
Se non ho capito male, il tema della diatriba dovrebbe essere come
chiamare le variabili che contengono numeri reali, sia per gli irrazionali
che per i razionali, e si proponeva di chiamarle per entrambi i casi
"variabili a virgola mobile".
Secondo me, invece, occorre distinguere i due casi: un numero irrazionale
(ad esempio la radice quadrata) non potra' mai essere rappresentato in
forma ESATTA da un computer, mentre un numero razionale potrebbe essere
rappresentato come una coppia di numeri interi, su cui puoi farci tutti i
calcoli che vuoi (nei limiti di overflow degli interi) e le operazioni
saranno sempre esatte.
Per cui, se e' vero che nella stragrande maggioranza dei casi le variabili
razionali coincidono con quelle floating-point, e' anche vero che i
razionali sono rappresentabili in forma esatta, e mi sembra piu'
corretto chiamare "variabili razionali" quelle (rare) strutture dati
fatte e studiate apposta per contenere i numeri razionali.
Ciao,
  Luca

 fatte e studiate apposta per contenere i numeri razionali.
Benissimo.
Chiamiamo variabili razionali quelli nella forma a/b
chiamiamo variabili irrazionali quelle nella forma a^b
chiamiamo variabile simbolica quella espressa con un'espressione.
Ma non ci rimane altro che chiamare "floating point" la variabile a
virgola mobile.

 virgola mobile.
D'accordissimo, ed e' quella che si usera' nel 99.999% dei casi per
quasiasi numero reale. Ma rimane quello 0.001% in cui e' possibile usare
un'altra rappresentazione "esatta" e "semplice" (una coppia di interi) per
i numeri razionali, anche dopo una qualsiasi quantita' di operazioni
elementari; non si puo' fare lo stesso con gli irrazionali.
Ciao,
  Luca

 elementari; non si puo' fare lo stesso con gli irrazionali.
Con il calcolo simbolico puoi restituire il risultato esatto, solo che
forse non si può chiamare questo risultato davvero "calcolato" :-)

 forse non si puï¿œ chiamare questo risultato davvero "calcolato" :-)
Anche perche' per tirare fuori un numero devi comunque passare per forza
da calcoli floating point, con piu' o meno le stesse problematiche di
precisione del calcolo diretto floating point.
Ciao!
  Luca

 precisione del calcolo diretto floating point.
Beh, non proprio.
L'output di 1/3 in virgola mobile è 0,333333.... con un numero
limitato di tre.
L'output di 1/3 calcolato in simbolico può essere 0,3 periodico.

 L'output di 1/3 calcolato in simbolico puï¿œ essere 0,3 periodico.
E l'output di sqrt(2)? I numeri razionali possono essere rappresentati con
il periodico, quelli irrazionali no....
Ciao,
  Luca

 di interi a lunghezza arbitraria.
Piu' precisamente, questi programmi usano internamente una
rappresentazione decimale, per cui non vengono nemmeno usate le capacita'
di calcolo intero a N bit della CPU (dove N e' il numero di bit
dell'architettura).
Una lettura molto interessante sull'argomento e' qui: 
 
http://en.wikipedia.org/wiki/Bigint
Ciao,
  Luca

 il periodico, quelli irrazionali no....
Ricopio dall'articolo che mi hai suggerito di leggere.
Arbitrary precision is used in applications where the speed of
arithmetic is not a limiting factor, or where precise results with
very large numbers is required. It should not be confused with the
symbolic computation provided by many computer algebra systems, which
represent numbers by expressions such as πsin(3), and can thus
represent any computable number with infinite precision.
Nel calcolo simbolico NON calcoleresti πsin(3) e quindi anche sqrt(2)
rimarrebbe in simbolico. L'eventuale calcolo avverrebbe solo alla
fine, con risoluzione arbitraria, floating point o integer che sia.

 con risoluzione arbitraria, floating point o integer che sia.
Si ma, a differenza dei razionali dove hai solo UNA divisione come
operazione finale, il calcolo finale per i simbolici ha tutte le
operazioni intermedie, con gli stessi problemi di precisione finita
(anche se arbitraria) delle operazioni floating-point. L'unico vantaggio
del calcolo simbolico e' che, dove possibile, puoi annullare/semplificare
risparmiando qualche passaggio, ma la perdita di precisione per ottenere
il risultato finale e' sempre incerta.
In conclusione: un numero razionale e' rappresentabile in maniera
esatta con variabili la cui struttura dati e' puramente numerica, mentre
non e' possibile rappresentare gli irrazionali in modo esatto con dati
puramente numerici.
Ciao,
  Luca

 puramente numerici.
Su questo non ho mai avuto dubbi.
Però non mi torna il fatto che disponendo di variabili in virgola
mobile con mantissa allungabile a seconda delle esigenze, io non possa
ottenere una specifica precisione sul risultato.

 ottenere una specifica precisione sul risultato.
E' possibile, ma devi portarti sempre a dietro dati di ingresso e tutte le
operazioni, a differenza delle variabili razionali dove hai solo 2 numeri.
Con i razionali devi tenere una struttura dati decisamente piu' complessa
e che e' forse improprio chiamarla "variabile", per non parlare degli
algoritmi necessari a mantenere la precisione desiderata: non impossibili
da implementare ma nemmeno cosi' banali.
Insomma, se dovessi esprimermi sull'esistenza di una "variabile razionale"
non avrei esitazioni a rispondere di si', mentre sull'esistenza di quella
"irrazionale" qualche dubbio mi viene.....
Ciao,
  Luca

 "irrazionale" qualche dubbio mi viene.....
Concordo.
Trovo solo improprio chiamare "variabile reale" quella a virgola
mobile.

GCPillan:

Il lato comico è che l'autore della Posizione A (io sono l'autore
della Posizione B) scrive oggi (sul NG dove questa disputa è nata)
quanto segue.
---------------------------------------------------------------------------------------------------
Ho letto quella discussione [su questo NG] ; le risposte sulla FPU
proseguono nell'equivoco di considerarla qualcosa che funziona di per
sé. Normale in un gruppo come it.comp.hardware.cpu; rimane sempre da
stabilire che cosa succede /dentro/ la FPU.
Ognuno ha il diritto di considerare di avere ragione in una
discussione; permettimi di pensare che non ne hai affatto. E che hai
dimostrato
ancora una volta di non sapere di ciò che parli (calcolo "simbolico",
in particolare).
---------------------------------------------------------------------------------------------------
In altre parole, è solo perché "ignoriamo" cosa succede DENTRO la FPU
che parliamo a vanvera di variabili a virgola mobile :-)
Certo, quando io parlo di limiti del floating point, mi sto
confondendo con il calcolo simbolico :-)

confondendo con il calcolo simbolico :-)
E vabb� ma allora in questi termini nessuno ha ragione, ed anche parlare di 
aritmetica intera risulta improprio, giacch� internamente tutte le unit� di 
calcolo lavorano con logica binaria, aggiungerei quindi una terza opzione 
che a questo punto dovrebbe essere incontestabile
Posizione C
Il calcolatore lavora internanente con aritmetica binara, e la presenza di 
unit� hardware e strumenti software consente l'esecuzione di operazioni tra 
numeri interi, a virgola fissa e mobile, ma che internamente, sono sempre 
ricondotte ad operazioni su numeri binari. 

 ricondotte ad operazioni su numeri binari.
Sì, però non rispondiamo al punto in discussione, ovvero a cosa è
dovuta la propagazione degli errori QUANDO un linguaggio di
programmazione, un applicativo o un programma di analisi utilizzano
delle variabili in floating point, per esempio a 64 bit.
A mio parere la limitazione è dovuta alla lunghezza finita di queste
variabili, che sono quelle con cui il programma e calcolatore si
passano i dati. I limiti di queste variabili floating point sono
stabilite dallo standard e non dalla capacità di programmazione del
singolo utente o dalla qualità del programma o dall'arrotondamento
entro la CPU. E poiché il calcolatore NON tratta questo tipo di
variabili come fossero interi, ma li tratta come mantissa ed
esponente, è errato dire che lavora solo su numeri interi e che ogni
altro formato dati è stabilito dal linguaggio e che questa limitazione
non ci interessa perché potremmo agire sui registri della CPU.

 non ci interessa perch� potremmo agire sui registri della CPU.
Questa non l'ho capita.
bye,
-- 
piergiorgio

 corretto, i.e. +1 o +0.
Non mi pare corretto riportare delle parole NON mie, come se fossero
mie.
Forse ho sbagliato io a riportarle, pensando di chiarire il pensiero
altrui.
In ogni caso, posso capire questo punto di vista (ovvero che su
mantissa ed esponente si fanno operazioni su interi) ma questo
ragionamento è fuorviante. Infatti questo non significa assolutamente
che il calcolatore tratti le variabili in virgola mobile come se
fossero interi. Ci sono differenze notevolissime anche su queste
operazioni "su interi": innanzitutto le mantisse devono essere
"allineate" prima della somma o sottrazione e questo è abissalmente
diverso da ciò che avviene tra variabili di tipo integer. Come
conseguenza abbiamo spesso la perdita dei bit meno significativi. Poi
abbiamo la normalizzazione che citi, che come conseguenza indiretta
porta all'assenza di overflow sulla mantissa. Per non citare le
differenze su altre operazioni matematiche e aspetti secondari come
l'arrotondamento.
Analogamente potremmo sostenere che in un calcolatore non si fanno mai
somme di interi, perché in fondo si fanno solo operazioni logiche tra
singoli bit. Allora dobbiamo forse sostenere che i calcolatori
lavorano solo su bit e non su interi? Quello che invece dobbiamo
chiederci, non è tanto come funziona il microprocessore ma quali
formati dati il microprocessore accetta in ingresso. Se accetta e
tratta come tali le variabili a virgola mobile allora si puà dire che
"funziona con variabili a virgola mobile". Semplice.
Eccezione fatta sulla faccenda dei calcoli su mantissa ed esponente,
sul resto non rispondo perché quelle da te commentate non erano parole
mie.

 mie.
Tra l'altro sbagliavo, la perdita di precisione con
i numeri FP non e` solo nel troncamento a seguito di
operazioni, ma anche nel fatto che, in base 2, non
tutti i numeri *finiti* in base 10 sono rappresentabili.
Per esempio 0.1 (base 10) ha rappresentazione infinita
in base 2 FP.
Quindi, ovviamente, si deve troncare nel momento in cui
si fa la conversione.
bye,
-- 
piergiorgio

 si fa la conversione.
E' un esempio che avevo già fatto io tempo fa.
0,1 parte limitato a 52 bit, esattamente come 1/3.
Questo 52 è solo un esempio, nel caso di "doppia precisione" IEEE 754.

 0,1 parte limitato a 52 bit, esattamente come 1/3.
Non esattamente, dato che 1/3 non e` rappresentabile
neanche in base 10.
Comunque sia, credo si stia dicendo la stessa cosa, anche
se forse per vie diverse.
bye,
-- 
piergiorgio

 se forse per vie diverse.
Io poi mi sto pure ripetendo...

 Io poi mi sto pure ripetendo...
Infatti... :-)
bye,
-- 
piergiorgio

 Non necessariamente, lo scrivi tu stesso qui sotto.
La rappresentazione interna sarà approssimata per definizione perché
lo standard di rappresentazione dei numeri in virgola mobile a
lunghezza finita prevede una rappresentazione approssimata su un
numero ben preciso di bit. Il caso particolare in cui questa
rappresentazione approssimata (ovvero limitata in lunghezza) combacia
con quella esatta, non cambia le cose perché anche questi numeri
"esatti" vengono trattati allo stesso modo dei numeri approssimati.