Grass double precision field

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Grass double precision field

Andrea Peri
Salve prosieguo il discorso /spiegazione dell'equivoco
con una appendice molto interessante a mio parere.

E anche per esemplificare un assunto per me sempre-verde: "Non esiste
la scelta migliore in assoluto"

Infatti il formato "double" è molto piu'
compatto del formato numeric.
E questo è un vantaggio.
Infatti mentre un double occupa 8 byte, un analogo numero espresso in
numeric occuperebbe
un numero di caratteri superiore.

Pero' il NUMERIC garantisce l' ESATTA archiviazione del numero.
Mentre il double ne garantisce l'archiviazione di una approssimazione.

Questo perche' il formato double segue la specifica FP64, ovvero la
regola mantissa-caratteristica.
http://en.wikipedia.org/wiki/Double_precision
Questo , abbinato al fatto che si usano una notazione binaria, porta
alla conseguenza ultima che
mentre molti numeri sono rappresentabili esattamente, ce ne sono
alcuni (non pochi per la verità)
che sono espressi solo approssimatamente.

Sono emsepi di questi numeri non esattamente rappresentabili in double
notation i seguenti:

0.01 , espresso in singola precisione (float) diviene
0.009999999776482582092285156250

http://www.binaryconvert.com/

0.1
la sua rappresentazione in binario a doppia precisione 64 bit di
precision (FP64 o double precision) è la seguente:

(0.1)10 -> (0x3FB999999999999A)16 -> (00111111 10111001 10011001
10011001 10011001 10011001 10011001 10011010)2

La quale riportata in decimale esprime il valore seguente:

1.00000000000000005551115123126E-1

cioe'
0.100000000000000005551115123126

Quindi esprimere il numero 0.1 in doppia precisione porta a compiere
un errore di
0.00000000000000005551115123126

Che sia tanto o poco dipende dal contesto in cui si va a usare tale numero.

In certe situazione (leggi coordinate di un vertice ) potrebbe anche
determinare un errore importante.
Ma anche in un campo di un DBF potrebbe esserlo.
Certo se si sta' esprimendo una quota o un qualcosa di altro che ha
gia' un suo oerrore di misurazione allora si puo' anche trascurare, ma
in altri contesti potrebbe non essere accettabile.
Per questo esiste ala notazione NUMERIC dove scrivendo semplicemente

Numeric 2,2  si impegna 4 caratteri e si memorizza ESATTAMENTE il valore 0.1

Saluti,


--
-----------------
Andrea Peri
. . . . . . . . .
qwerty àèìòù
-----------------
_______________________________________________
[hidden email]
http://lists.gfoss.it/cgi-bin/mailman/listinfo/gfoss
Questa e' una lista di discussione pubblica aperta a tutti.
Non inviate messaggi commerciali.
I messaggi di questa lista non hanno relazione diretta con le posizioni dell'Associazione GFOSS.it.
605 iscritti al 10.7.2012
Reply | Threaded
Open this post in threaded view
|

Re: Grass double precision field

a.furieri
On Fri, 30 Nov 2012 10:19:22 +0100, Andrea Peri wrote:

> Questo , abbinato al fatto che si usano una notazione binaria, porta
> alla conseguenza ultima che mentre molti numeri sono rappresentabili
> esattamente, ce ne sono alcuni (non pochi per la verità) che sono
> espressi
> solo approssimatamente.
>
> Sono emsepi di questi numeri non esattamente rappresentabili in
> double
> notation i seguenti:
>
> 0.01 , espresso in singola precisione (float) diviene
> 0.009999999776482582092285156250
>
> http://www.binaryconvert.com/
>
> 0.1
> la sua rappresentazione in binario a doppia precisione 64 bit di
> precision (FP64 o double precision) è la seguente:
>
> (0.1)10 -> (0x3FB999999999999A)16 -> (00111111 10111001 10011001
> 10011001 10011001 10011001 10011001 10011010)2
>
> La quale riportata in decimale esprime il valore seguente:
>
> 1.00000000000000005551115123126E-1
>
> cioe'
> 0.100000000000000005551115123126
>

Andrea,

le tue sono Sante Parole: aggiungo solo che quanto tu dici vale
solo in un idilliaco mondo ideale del tutto teorico.
la dura realta' del mondo fisico e' ancora peggiore :-D

perche' occorre mettere nel conto le diverse implementazioni delle
librerie di runtime (che sono sempre e comunque alla base di tutto
quanto il sw, a prescindere del linguaggio usato).
e qua si scopre inevitabilmente che diverse versioni e/o diverse
implementazioni forniscono risultati leggermente differenti.

giusto per fare un banale esempio in C:

...
double x = atof("1.2");
printf("%1.16f\n", x);
...

a seconda della piattaforma che usi scoprirai che puoi ottenere
(piu' o meno a casaccio):
1.2000000000000000
1.2000000000000001
1.1999999999999999

te lo dico con assoluta certezza di causa, visto che ho perso le
ultime settimane per mettere a punto la test-coverage di splite.

e ti assicuro che ho dovuto sudare le mitiche sette camicie prima
di riuscire faticosamente a mettere a punto una serie di test numerici
(coordinate) che tornassero sempre e comunque gli stessi identici
risultati su Debian, Fedora e WinOZ sia a 32 che a 64 bit.

con un'ultima insospettata regressione finale quando poi ho fatto
girare tutta quanta la test-coverage sotto Valgrind, ed ho cosi'
inopinatamente scoperto che in questo ambiente di test alcuni
testcases ritornano ancora altri valori differenti :-P
(non del tutto sorprendente, visto che Valgrind in pratica non
usa la CPU fisica ma usa una macchina virtuale sua propria che
emula i codici macchina x86).

ciao Sandro





--
Il messaggio e' stato analizzato alla ricerca di virus o
contenuti pericolosi da MailScanner, ed e'
risultato non infetto.

_______________________________________________
[hidden email]
http://lists.gfoss.it/cgi-bin/mailman/listinfo/gfoss
Questa e' una lista di discussione pubblica aperta a tutti.
Non inviate messaggi commerciali.
I messaggi di questa lista non hanno relazione diretta con le posizioni dell'Associazione GFOSS.it.
605 iscritti al 10.7.2012
Reply | Threaded
Open this post in threaded view
|

Re: Grass double precision field

Sandro Santilli
On Fri, Nov 30, 2012 at 11:04:30AM +0100, [hidden email] wrote:

> e ti assicuro che ho dovuto sudare le mitiche sette camicie prima
> di riuscire faticosamente a mettere a punto una serie di test numerici
> (coordinate) che tornassero sempre e comunque gli stessi identici
> risultati su Debian, Fedora e WinOZ sia a 32 che a 64 bit.
>
> con un'ultima insospettata regressione finale quando poi ho fatto
> girare tutta quanta la test-coverage sotto Valgrind, ed ho cosi'
> inopinatamente scoperto che in questo ambiente di test alcuni
> testcases ritornano ancora altri valori differenti :-P
> (non del tutto sorprendente, visto che Valgrind in pratica non
> usa la CPU fisica ma usa una macchina virtuale sua propria che
> emula i codici macchina x86).

Aggiungo che anche le stesse architetture possono tornare valori
diversi quando si cambiano i flag di compilazione. L'uso o meno
di registri allarga o diminuisce i bit a disposizione nelle
operazioni cambiando i risultati finali. L'uso dei registri dipende
dallo scrivere o meno una variabile in memoria, quindi:

 a = ( b / c ) * 2;

potrebbe essere diverso da

 t = b / c; // store it !
 a = t * 2;

E la seconda potrebbe essere di nuovo come la prima se si chiede
al compilatore di ottimizzare, e se il compilatore e' capace di
farlo (quindi dipende pure dalla versione).

In GEOS siamo _pieni_ di questi problemi... uno dei piu' recenti
tentativi di "stabilizzazione" e' stato quello di aggiungere uno
switch -ffloat-store alla linea di compilazione (ma funziona solo
con GCC).

--strk;
_______________________________________________
[hidden email]
http://lists.gfoss.it/cgi-bin/mailman/listinfo/gfoss
Questa e' una lista di discussione pubblica aperta a tutti.
Non inviate messaggi commerciali.
I messaggi di questa lista non hanno relazione diretta con le posizioni dell'Associazione GFOSS.it.
605 iscritti al 10.7.2012
Reply | Threaded
Open this post in threaded view
|

Re: Grass double precision field

Carlo Cormio
In reply to this post by Andrea Peri
Buongiorno a tutti,

questa discussione sul formato dei dati è molto interessante, mi ci sono imbattuto spesso e nella maggior parte dei casi ho abbozzato. Sarebbe molto bello ed utile creare una pagina con le osservazioni di Andrea ed Alessandro, su GFOSS.it o altrove, dove più opportuno.

Non so dove nè come metterci le mani, ma se volete (magari non avete tempo o voglia) posso provare a farlo anche io :)

A proposito, sto seguendo un tesista nell'aggiornamento del database nazionale dei siti minerari (un progetto ISPRA - Università di Bologna), che oltre all'implementazione di nuove funzionalità specifiche prevede il passaggio da MS Access a SQLite / Spatialite (yeah!!!), con l'obiettivo finale di renderlo accessibile tramite webgis, QGIS, tablet, ecc, ecc (un passo alla volta :)).

Dopo una lunga (ed in parte sofferta) analisi dei data type in SQLite siamo arrivati alla conclusione che i dati numerici nelle tabelle avranno sempre diverse cifre decimali, anche quando non necessarie (in termini di precisione del dato), e che se vogliamo visualizzare un dato "arrorondato" basta usare un'opportuna query SQL. E? tutto giusto o sto sbagliando un bel po' di cose?

Complimenti a tutti e buona giornata,

Carlo

Il 30/11/2012 11:04, [hidden email] ha scritto:
On Fri, 30 Nov 2012 10:19:22 +0100, Andrea Peri wrote:
Questo , abbinato al fatto che si usano una notazione binaria, porta
alla conseguenza ultima che mentre molti numeri sono rappresentabili
esattamente, ce ne sono alcuni (non pochi per la verità) che sono espressi
solo approssimatamente.

Sono emsepi di questi numeri non esattamente rappresentabili in double
notation i seguenti:

0.01 , espresso in singola precisione (float) diviene
0.009999999776482582092285156250

http://www.binaryconvert.com/

0.1
la sua rappresentazione in binario a doppia precisione 64 bit di
precision (FP64 o double precision) è la seguente:

(0.1)10 -> (0x3FB999999999999A)16 -> (00111111 10111001 10011001
10011001 10011001 10011001 10011001 10011010)2

La quale riportata in decimale esprime il valore seguente:

1.00000000000000005551115123126E-1

cioe'
0.100000000000000005551115123126


Andrea,

le tue sono Sante Parole: aggiungo solo che quanto tu dici vale
solo in un idilliaco mondo ideale del tutto teorico.
la dura realta' del mondo fisico e' ancora peggiore :-D

perche' occorre mettere nel conto le diverse implementazioni delle
librerie di runtime (che sono sempre e comunque alla base di tutto
quanto il sw, a prescindere del linguaggio usato).
e qua si scopre inevitabilmente che diverse versioni e/o diverse
implementazioni forniscono risultati leggermente differenti.

giusto per fare un banale esempio in C:

...
double x = atof("1.2");
printf("%1.16f\n", x);
...

a seconda della piattaforma che usi scoprirai che puoi ottenere
(piu' o meno a casaccio):
1.2000000000000000
1.2000000000000001
1.1999999999999999

te lo dico con assoluta certezza di causa, visto che ho perso le
ultime settimane per mettere a punto la test-coverage di splite.

e ti assicuro che ho dovuto sudare le mitiche sette camicie prima
di riuscire faticosamente a mettere a punto una serie di test numerici
(coordinate) che tornassero sempre e comunque gli stessi identici
risultati su Debian, Fedora e WinOZ sia a 32 che a 64 bit.

con un'ultima insospettata regressione finale quando poi ho fatto
girare tutta quanta la test-coverage sotto Valgrind, ed ho cosi'
inopinatamente scoperto che in questo ambiente di test alcuni
testcases ritornano ancora altri valori differenti :-P
(non del tutto sorprendente, visto che Valgrind in pratica non
usa la CPU fisica ma usa una macchina virtuale sua propria che
emula i codici macchina x86).

ciao Sandro






_______________________________________________
[hidden email]
http://lists.gfoss.it/cgi-bin/mailman/listinfo/gfoss
Questa e' una lista di discussione pubblica aperta a tutti.
Non inviate messaggi commerciali.
I messaggi di questa lista non hanno relazione diretta con le posizioni dell'Associazione GFOSS.it.
605 iscritti al 10.7.2012
Reply | Threaded
Open this post in threaded view
|

Re: Grass double precision field

Sandro Santilli
On Fri, Nov 30, 2012 at 12:24:29PM +0100, carlo cormio wrote:

> Dopo una lunga (ed in parte sofferta) analisi dei data type in SQLite siamo arrivati alla conclusione che i dati numerici nelle tabelle avranno sempre diverse cifre decimali, anche quando non necessarie (in termini di precisione del dato), e che se vogliamo visualizzare un dato "arrorondato" basta usare un'opportuna query SQL. E? tutto giusto o sto sbagliando un bel po' di cose?

Controllare la precisione con una query SQL "arrotondante" mi sembra la cosa
migliore. La discussione fatta finora era piu' che altro per avere un'idea di
quale fosse la massima precisione consentita.

PS: complimenti per il progetto di migrazione a software libero !

--strk;
_______________________________________________
[hidden email]
http://lists.gfoss.it/cgi-bin/mailman/listinfo/gfoss
Questa e' una lista di discussione pubblica aperta a tutti.
Non inviate messaggi commerciali.
I messaggi di questa lista non hanno relazione diretta con le posizioni dell'Associazione GFOSS.it.
605 iscritti al 10.7.2012
Reply | Threaded
Open this post in threaded view
|

Re: Grass double precision field

giuliano su Tiscali
In reply to this post by Carlo Cormio
On Fri, 30 Nov 2012 12:24:29 +0100
carlo cormio <[hidden email]> wrote:

>
> Buongiorno a tutti,
>
>
>
> questa discussione sul formato dei dati è molto interessante, ....
> .......... Sarebbe
> molto bello ed utile creare una pagina con le osservazioni di Andrea ed
> Alessandro, su GFOSS.it o altrove, dove più opportuno.

+1;


> Non so dove nè come metterci le mani, ma se volete (magari non avete tempo
> o voglia) posso provare a farlo anche io :)

+1 :-)

 
> Complimenti a tutti e buona giornata,
>
> Carlo

ciao,
giuliano
_______________________________________________
[hidden email]
http://lists.gfoss.it/cgi-bin/mailman/listinfo/gfoss
Questa e' una lista di discussione pubblica aperta a tutti.
Non inviate messaggi commerciali.
I messaggi di questa lista non hanno relazione diretta con le posizioni dell'Associazione GFOSS.it.
605 iscritti al 10.7.2012