77 messaggi dal 16 maggio 2002
Salve,

ho una forte confusione sull'uso e differenze fra questi due tipi di dati, credo sia corretto dire che con i decimal non ci sono problemi di precisione e quindi devono essere usati per rappresentare dati di tipo valuta, mentre con i double si, e potrebbe verificarsi che inviando al DB ad esempio il valore 0,1 ci ritornerà in lettura 0,099999.
Ora mi chiedo se è cosi quando ha senso utilizzare i double con tranquillità?

ad esempio mi viene il dubbio che sia sempre sbagliato usarlo per rappresentare valori tipo lo sconto, il ricarico, o misure tipo il peso l'altezza ecc.

nel caso di lettura di tipi decimal con Sql server, ovviamente mi ritrovo aggiunti degli zeri in base alla precisione impostata, non sono ancora riuscito a trovare in .net nessuna funzione che mi tolga gli zeri non significativi e che quindi in questi casi si comporti in questo modo:

1,000 --> 1
1,0300 --> 1,03

esiste un modo per far questo senza gestirle come stringa...?

ho letto da qualche parte che qualcuno usa convertire lato client tutti i decimal in double eseguire i vari calcoli e riconvertire il risultato in decimal, in questo modo nella conversione da decimal a double non si ha una perdita di precisione?

Grazie in aniticipo per le risposte
1.976 messaggi dal 27 luglio 2005
Contributi
salve,
pipponet ha scritto:
Salve,

ho una forte confusione sull'uso e differenze fra questi due tipi di dati, credo sia corretto dire che con i decimal non ci sono problemi di precisione e quindi devono essere usati per rappresentare dati di tipo valuta, mentre con i double si, e potrebbe verificarsi che inviando al DB ad esempio il valore 0,1 ci ritornerà in lettura 0,099999.
Ora mi chiedo se è cosi quando ha senso utilizzare i double con tranquillità?

ad esempio mi viene il dubbio che sia sempre sbagliato usarlo per rappresentare valori tipo lo sconto, il ricarico, o misure tipo il peso l'altezza ecc.

nel caso di lettura di tipi decimal con Sql server, ovviamente mi ritrovo aggiunti degli zeri in base alla precisione impostata, non sono ancora riuscito a trovare in .net nessuna funzione che mi tolga gli zeri non significativi e che quindi in questi casi si comporti in questo modo:

1,000 --> 1
1,0300 --> 1,03

esiste un modo per far questo senza gestirle come stringa...?

ho letto da qualche parte che qualcuno usa convertire lato client tutti i decimal in double eseguire i vari calcoli e riconvertire il risultato in decimal, in questo modo nella conversione da decimal a double non si ha una perdita di precisione?

Grazie in aniticipo per le risposte


la tua analisi e' corretta... i tipi di dati approssimati (float, reale etc) non vanno usati quando uno scarto di approssimazione puo' essere influente ai fini della propria modellazione della realta'... tipicamente, i dati relativi a valute, non andrebbero mai salvati con quei tipi di dato...
riguardo i numeri non significativi, il "workarond" da te citato non mi e' noto, e mi pare anche possibile fonte di problematiche...
personalmente non lo utilizzerei..
se hai chiaramente definito un tipo di dato decimal (10,4),
DECLARE @d decimal (10,4);
SET @d = 1;
SELECT @d;

il risultato sara' sempre alla massima precisione da te impostata..
puoi eventualmente effettuare un cast esplicito, similarmente a
DECLARE @d decimal (10,4);
SET @d = 1.1993;
SELECT @d;
DECLARE @d1 decimal (10,2);
SET @d1 = @d;
SELECT @d1, CONVERT (decimal(10,2), @d);
che pero' non "tronca" il valore ma lo arrotonda sempre, come anche argomentato in http://msdn2.microsoft.com/en-us/library/ms187928.aspx

puoi un po' "giocare" con le conversioni in stringa, tipo
DECLARE @d decimal (10,4);
SET @d = 1.1993;
SELECT CONVERT(decimal(10,2),LEFT(CONVERT(varchar,@d),4));
ma sicuramente non e' un bel modo di operare... d'altronde, se hai ad esempio definito un tipo di dato a 4 decimali probabilmente ce ne sara' un motivo ben preciso.. anche gli 0 non significativi avrebbero, almeno per me, un significato ben preciso che va al di la' della rappresentazione su una UI, ma attengono proprio alla definizione del dominio al quale appartengono..
e personalmente non mi piacerebbe ad esempio veder ritornato un "elenco" simile a
1
1.1
1.1234
ma preferirei sempre
1.0000
1.1000
1.1234
saluti

Andrea Montanari
http://www.hotelsole.com - http://www.hotelsole.com/asql/index.php
77 messaggi dal 16 maggio 2002
Grazie Andrea per la risposta domenicale... ;-)

volendo approfondire il discorso della perdita di precisione nel caso di float in sql server, è corretto dire che un'approssimazione e quindi una perdita di precisione si ha solamente a partire da un numero di cifre a salire?
ho notato che usando lato client l'equivalente in .net 1.1 dei float di sql server, i double, superando le 15 cifre totali ottengo un'approssimazione nel DB, è solo questo il caso oppure si ha un'approssimazione che dipende anche da altro tipo dalla conversione in binario, se è corretto dire cosi...?

per quel che riguarda il non voler visualizzare gli zeri non significativi, ti faccio un esempio banale, ho un campo quantità che riguarda un certa unità di misura, in base a quest'ultima verrà utlizzato il campo quantità con valori che possono essere anche solo interi o reali o tutte e due le cose, quindi nel caso di valori interi perchè ad esempio l'unità di misura è "pezzi" non mi piaceva far visualizzare gli zeri non significativi, non solo ma in questo caso non saprei nemmeno a priori che scala usare o almeno ne dovrei mettere una massima...

cosa ne pensi?

Grazie
1.976 messaggi dal 27 luglio 2005
Contributi
salve,
pipponet ha scritto:
Grazie Andrea per la risposta domenicale... ;-)

volendo approfondire il discorso della perdita di precisione nel caso di float in sql server, è corretto dire che un'approssimazione e quindi una perdita di precisione si ha solamente a partire da un numero di cifre a salire?
ho notato che usando lato client l'equivalente in .net 1.1 dei float di sql server, i double, superando le 15 cifre totali ottengo un'approssimazione nel DB, è solo questo il caso oppure si ha un'approssimazione che dipende anche da altro tipo dalla conversione in binario, se è corretto dire cosi...?

io ci starei attento...
scrivi ad esempio in SQL Server 2000:
DECLARE @f float;
SET @f = 0.1;
SELECT @f;
IF @f = 0.1
PRINT 'Uguali'
ELSE
PRINT 'Diversi'
--<--------
0.10000000000000001
Uguali

e cio' puo' parecchio confondere...

continua con
DECLARE @f float(25), @f2 float(24);
SELECT @f = 0.1234567890;
SELECT @f2 = @f;

SELECT @f2 AS [F2], @f AS [F];
IF @f2 = @f
PRINT 'Uguali';
ELSE
Print 'Diversi';
--<--------
F2 F
------------- ----------------------
0,1234568 0,123456789
Diversi

a me basta per cercare di usarli solo se necessari, quindi non in ambito commerciale


per quel che riguarda il non voler visualizzare gli zeri non significativi, ti faccio un esempio banale, ho un campo quantità che riguarda un certa unità di misura, in base a quest'ultima verrà utlizzato il campo quantità con valori che possono essere anche solo interi o reali o tutte e due le cose, quindi nel caso di valori interi perchè ad esempio l'unità di misura è "pezzi" non mi piaceva far visualizzare gli zeri non significativi, non solo ma in questo caso non saprei nemmeno a priori che scala usare o almeno ne dovrei mettere una massima...
cosa ne pensi?
Grazie

a botta secca ti dico che e' sbagliato il dominio
il dominio utilizzato dovrebbe essere coerente e rilevante per tutte la valorizzazioni che esso puo' dover assumere...
se definisci un dominio con precisione, e quindi con decimali, chiaramente tutti i valori "ereditano" questa proprieta'.. saranno tutti valori con decimali, a prescindere della presenza di soli interi o meno...
potremmo anche dire che' e' sbagliata la definizione del predicato, visto che un'entita' deve poter "accogliere" solo elementi omogenei tra loro... se l'entità e' ad esempio [Animali] chiaramente l'attributo [quantita'] non potra' essere una frazione o un valore con decimali...
potremmo argomentare che il predicato sia {PorzioneAlimentare} (scusami la deformazione professionale  ), quindi valorizzabile come
{PorzioneAlimentare [CodiceLasagna, 1]}
{PorzioneAlimentare [CodiceLasagna, 0.5]} (per indicare mezza porzione)
ma non ha comunque senso nella normalizzazione relazionale...
se poi aggiungi che un valore dipende dalla valorizzazione di un altro,
... il campo quantità con valori che possono essere anche solo interi o reali o tutte e due le cose...

non stai parlando di "cose" tra loro omogenee..
a seconda della "enumerazione" del valore attribuito ad una colonna, il predicato puo' riferisi a vegetali, animali, minerali..
capisco l'esigenza di modellazione, e se non puoi/vuoi ridefinire l'architettura devi chiaramente utilizzare il dominio che consenta "tutte" le possibili valorizzazioni, ma a questo punto devi giocoforza fare i conti con la scelta effettuata per la rappresentazione della tua "realta'"..
solamente lato client puoi, in funzione del valore dell'attributo che ridefinisce il concetto del predicato stesso, giocare sulla "renderizzazione" dei restanti valori... quindi se trattasi di "bottiglia di vino" sara' [Unita'] (con rappresentazione intera), dove invece "formaggio" sara' [Peso] (con rappresentazione decimale)...
saluti

Andrea Montanari
http://www.hotelsole.com - http://www.hotelsole.com/asql/index.php

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.