2009-07-30 16 views
263

Ho un paio di proprietà in C# che sono double e voglio memorizzarle in una tabella in SQL Server, ma ho notato che non c'è il tipo double, quindi cosa è meglio usare, decimal o float?Che cosa rappresenta un doppio nel server sql?

Questo memorizzerà i valori di latitudine e longitudine, quindi ho bisogno della precisione più precisa.

Grazie per le risposte finora.

risposta

318
float 

Oppure, se si vuole andare vecchia scuola:

real 

È inoltre possibile utilizzare galleggiante (53), ma significa la stessa cosa di galleggiante.

("reale" è equivalente a stare a galla (24), non galleggiare/galleggiante (53).)

Il decimale (x, y) Tipo SQL Server è per quando si desidera esatto decimale numeri anziché virgola mobile (che possono essere approssimazioni). Ciò è in contrasto con il tipo di dati "decimale" C#, che è più simile a un numero in virgola mobile a 128 bit.

MSSQL galleggiante non ha esattamente la stessa precisione del 64 bit doppio tipo a .NET (leggera differenza nella mantissa IIRC), ma è un abbastanza vicino abbinare la maggior parte degli utilizzi.

Per rendere le cose più confuse, un "float" in C# è solo 32 bit, quindi sarebbe più equivalente in SQL al tipo reale/mobile (24) in MSSQL che float/float (53).

Nel tuo caso specifico uso ... Tutto ciò che serve è 5 posti dopo la virgola per rappresentare latitudine e longitudine in circa la precisione di un metro, e avete solo bisogno di fino a tre cifre prima del punto decimale per i gradi. Float (24) o decimale (8,5) si adatta meglio alle tue esigenze in MSSQL e l'uso di float in C# è abbastanza buono, non è necessario il doppio. In effetti, i tuoi utenti probabilmente ti ringrazieranno per arrotondare a 5 cifre decimali anziché avere un gruppo di cifre insignificanti che arrivano per la corsa.

+1

Tu dici float, David dice decimale, ora sono ancora più confuso :) – Xaisoft

+0

Sto usando il doppio in C# e questi valori saranno valori di latitudine e longitudine nelle rispettive colonne. – Xaisoft

+1

Devo concorrere, e ammetto che ero fuori base. Sono stato introdotto al decimale nel mondo IBM DB2, in cui il decimale è un tipo di dati reale, supportato da tutti i tipi di codice e dal database su piattaforme IBM. Non che non sia un vero e proprio datatype nel mondo MS, ma non è supportato così come nel campo IBM. Ci scusiamo per aver creato confusione. – DaveN59

5

Per SQL Sever:

tipo decimale è a 128 bit con segno numero Float è un numero con segno a 64 bit.

La vera risposta è Float, non ero corretto sui decimali.

Il motivo è se si utilizza un decimale non si riempirà mai 64 bit del tipo decimale.

Sebbene il decimale non ti dia un errore se tenti di utilizzare un tipo int.

Here è un grafico di riferimento piacevole dei tipi.

+0

Ora è ancora più confuso con due risposte diverse: p – Xaisoft

+0

Non essere confuso. Questa risposta è sbagliata. Decimal è un tipo di base 10; Float (in SQL Server e CLR) è un tipo di base-2. –

+0

No, le mappe decimali decimali –

7

float in SQL Server ha effettivamente [modifica: quasi] la precisione di un "doppio" (in un senso C#).

float è un sinonimo di float(53). 53 sono i bit della mantissa.

.NET double utilizza 54 bit per la mantissa.

+2

In realtà, IIRC, double in .NET utilizza una mantissa a 52 bit e un esponente a 11 bit. – richardtallent

+0

Sarò dannatamente; hai ragione! Mi chiedo cosa faccia SQL con il bit in più; non è usato per l'esponente. Se così fosse, l'esponente salirà a + -616 invece di + -308. Forse per tracciare NULL? –

+0

Ora sono confuso. Ogni elemento di prova indica che usano lo stesso formato (come tutto il resto in Windows). E perché non dovrebbero? Non riesco a trovare una dichiarazione definita sulla rappresentazione bit a bit in SQL Server (oltre alla pagina della guida per float). Pubblicherò una correzione se lo scoprirò. –

5

C'è un great thread on MSDN che descrive la differenza principale tra FLOAT e decimali. In breve, Float è approssimativo e non può rappresentare alcuni valori.

Guarda la risposta accettata.

+1

Anche Double in C# è approssimativo, per lo stesso motivo. Quindi, float (o, il float più lungo (53)) è la migliore corrispondenza per il doppio. – richardtallent

13

float è l'equivalente più vicino.

SqlDbType Enumeration

Edit:

Per Lat/Long come detto OP.

Un metro è 1/40.000.000 di latitudine, 1 secondo è di circa 30 metri. Float/double ti danno 15 cifre significative. Con qualche aritmetica mentale rapida e dubbia ... gli errori di arrotondamento/approssimazione sarebbero la lunghezza di questo punto di riempimento -> "."

+1

Vendi il tuo schermo tecnico ad Apple e fai miliardi! (L'aritmetica veloce mi dice che hai la risoluzione più estrema che abbia mai sentito, anche a latitudini vicine al Polo Nord/Sud, circa un miliardo di volte superiore al mio.) –

2

Sembra che sia possibile scegliere. Se scegli il float, potresti perdere 11 cifre di precisione. Se è accettabile, provaci - a quanto pare i designer di Linq hanno pensato che fosse un buon compromesso.

Tuttavia, se l'applicazione richiede tali cifre aggiuntive, utilizzare i decimali. Decimal (implementato correttamente) è molto più accurato di un float in ogni caso - nessuna traduzione disordinata dalla base 10 alla base 2 e viceversa.

+0

Come altri hanno notato, anche il doppio è impreciso. Il mio voto è per float ... – DaveN59

+0

Questo è per la memorizzazione dei valori di latitudine e longitudine. Questo fa la differenza? – Xaisoft

+0

Questo è semplicemente sbagliato ... sia float/float (53) in MSSQL che double in C# hanno circa 15 cifre di precisione. Non sono esattamente uguali, ma abbastanza vicini. Il decimale, d'altra parte, è un overkill completo per la memorizzazione di un double, e deve tornare alla base 2 per tutti i calcoli in SQL Server e tornare a C# come doppio. – richardtallent

2

@Achilles Eccellente! Siamo venuti qui per il doppio stato per il TinyInt.

Ecco un caso interruttore parzialmente fatto per la conversione tra dataTable e SQL:

switch (columnDataTypeList[i]) 
{ 
    case "System.String": 
     columnDataTypeList[i] = "VARCHAR(MAX)"; 
     break; 
    case "System.Int32": 
     columnDataTypeList[i] = "INT"; 
     break; 
    case "System.DateTime": 
     columnDataTypeList[i] = "DATE"; 
     break; 
    case "System.Double": 
     columnDataTypeList[i] = "FLOAT"; 
     break; 
} 

La stringa può essere un problema essere sicuri di modificarla alle proprie esigenze, ma il doppio dovrebbe funzionare, che è la questione a mano.

20

Inoltre, here è una buona risposta per il mapping dei tipi SQL-CLR con un grafico utile.

Da quel post (da David): enter image description here

Problemi correlati