2009-07-30 19 views
263

Mam kilka właściwości w C#, które są double i chcę je przechowywać w tabeli w SQL Server, ale zauważyłem, że nie ma typu double, więc co najlepiej jest użyć, decimal lub float?Co oznacza serwer podwójny w sql?

Spowoduje to zapisanie wartości szerokości i długości geograficznej, więc potrzebuję najbardziej dokładnej precyzji.

Dzięki za odpowiedzi do tej pory.

Odpowiedz

318
float 

Lub jeśli chcesz iść starej szkoły:

real 

Można również użyć pływaka (53), ale oznacza to samo, co pływaka.

("prawdziwy" jest równoznaczne z pływaka (24), nie unoszą/float (53)).

The przecinku (x, y) typu SQL Server jest dla kiedy chcesz dokładny dziesiętny liczby, a nie zmiennoprzecinkowe (które mogą być przybliżeniami). Jest to przeciwieństwo typu danych "dziesiętnych" C#, który jest bardziej podobny do 128-bitowego numeru zmiennoprzecinkowego.

MSSQL pływak nie posiada dokładnie taka sama precyzja jak 64-bitowym podwójnym typu w .NET (niewielka różnica w mantysy IIRC), ale jest to na tyle blisko dopasować większość zastosowań.

Aby sprawić, by sytuacja była bardziej zagmatwana, "float" w języku C# ma tylko wartość 32-bitową, więc byłby bardziej równoważny w SQL dla typu real/float (24) w MSSQL niż float/float (53).

W konkretnego przypadku użycia ... Wszystko czego potrzebujesz to 5 miejsc po przecinku do reprezentowania szerokości i długości geograficznej odległości około jednego metra precyzją, a wystarczy tylko do trzech cyfr przed przecinkiem dla stopnie. Float (24) lub dziesiętny (8,5) najlepiej pasuje do twoich potrzeb w MSSQL, a używanie float w C# jest wystarczająco dobre, nie potrzebujesz podwójnego. W rzeczywistości Twoi użytkownicy będą prawdopodobnie dziękowali za zaokrąglenia do 5 miejsc po przecinku, zamiast kupować nieznaczną liczbę cyfr.

+1

Mówisz pływak, David mówi dziesiętnie, teraz jestem jeszcze bardziej zdezorientowany :) – Xaisoft

+0

Używam podwójnych w C#, a wartościami tymi będą wartości szerokości i długości geograficznej w odpowiednich kolumnach. – Xaisoft

+1

Muszę się zgodzić i przyznać, że byłem poza bazą. Wprowadzono dziesiętny w środowisku IBM DB2, gdzie dziesiętny jest rzeczywistym typem danych, obsługiwanym przez wszystkie smaki kodu i bazy danych na platformach IBM. Nie chodzi o to, że nie jest to prawdziwy typ danych w świecie MS, ale nie jest obsługiwany tak dobrze, jak w obozie IBM. Przepraszam za tworzenie zamieszania. – DaveN59

5

Dla SQL Sever:

dziesiętny Typ jest 128 bitowa liczba Pływak jest 64 bitowa liczba podpisane.

Prawdziwa odpowiedź to Float, Niepoprawnie wprowadzono wartość dziesiętną.

Powód jest taki, że jeśli użyjesz dziesiętnych, nigdy nie wypełnisz 64-bitowego typu dziesiętnego.

Mimo że wartość dziesiętna nie spowoduje błędu, jeśli spróbujesz użyć typu int.

Here to ładny schemat referencyjny typów.

+0

Teraz jest jeszcze bardziej zagmatwany z dwiema różnymi odpowiedziami: p – Xaisoft

+0

Nie bądź zmieszany. Ta odpowiedź jest błędna. Dziesiętny jest typem podstawowym-10; Float (w SQL Server i CLR) jest typem base-2. –

+0

Nie, mapy dziesiętne na dziesiętne –

7

float w SQL Server faktycznie ma [edytuj: prawie] precyzję "podwójnego" (w sensie C#).

float to synonim nazwy float(53). 53 to fragmenty mantysy.

NET double wykorzystuje 54 bitów dla podstawa.

+2

W rzeczywistości IIRC, podwójny w .NET używa 52-bitowego mantysy i 11-bitowego wykładnika. – richardtallent

+0

Będę cera; masz rację! Zastanawiam się, co SQL robi z dodatkowym bitem; nie jest używane dla wykładnika. Jeśli tak, wykładnik wzrośnie do +616 zamiast do -308. Może do śledzenia NULL? –

+0

Teraz jestem zdezorientowany. Każdy dowód wskazuje na to, że używają tego samego formatu (co wszystko inne w systemie Windows). I dlaczego nie mieliby tego zrobić? Nie mogę znaleźć jednoznacznej instrukcji na reprezentacji bitowej w SQL Server (oprócz strony pomocy dla float). Wezwę poprawkę, jeśli się dowiem. –

5

Jest great thread on MSDN opisujący podstawową różnicę między pływaka i dziesiętnych. W skrócie, Float jest przybliżony i nie może reprezentować niektórych wartości.

Sprawdź zaakceptowaną odpowiedź.

+1

Podwójne C# jest również przybliżone, z tego samego powodu. Tak więc, float (lub dłuższy float (53)) najlepiej pasuje do double. – richardtallent

13

float jest najbliższym odpowiednikiem.

SqlDbType Enumeration

Edit:

Dla Lat/Długi jak wspomniano OP.

Licznik jest 1/40000000 o szerokości 1 sekunda wynosi około 30 metrów. Float/double daje 15 znaczących liczb. Z pewną szybką i podejrzaną arytmetyką mentalną ... błędy zaokrągleń/aproksymacji będą dotyczyły długości tego zatrzymania wypełnienia -> "."

+1

Sprzedaj swój ekran technologiczny Apple i zarób miliardy! (Szybka arytmetyka mówi mi, że masz najbardziej ekstremalną rozdzielczość, o jakiej kiedykolwiek słyszałem, nawet na szerokościach geograficznych w pobliżu bieguna północnego/południowego, około miliard razy większą niż moja.) –

2

Wygląda na to, że możesz wybrać i wybrać. Jeśli wybierzesz zmiennoprzecinkowe, możesz stracić 11 cyfr precyzji. Jeśli to jest do przyjęcia, idźmy na to - najwyraźniej projektanci Linq uważali to za dobry kompromis.

Jeśli jednak aplikacja potrzebuje tych dodatkowych cyfr, użyj wartości dziesiętnej. Dziesiętny (zaimplementowany poprawnie) jest o wiele dokładniejszy niż spławik - nie ma bałaganu z bazy 10 do bazy 2 iz powrotem.

+0

Jak zauważyli inni, podwójność również jest nieprecyzyjna. Mój głos jest przeznaczony na float ... – DaveN59

+0

Służy do przechowywania wartości szerokości i długości geograficznej. Czy to robi różnicę? – Xaisoft

+0

To jest po prostu niepoprawne ... zarówno float/float (53) w MSSQL, jak i double in C# mają około 15 cyfr precyzji. Nie są dokładnie takie same, ale wystarczająco blisko. Z drugiej strony, dziesiętny jest zupełnym przeskokiem do przechowywania podwójnego, i musi wrócić do podstawy 2 dla wszystkich obliczeń w SQL Server, i wrócić do C# jako podwójne. – richardtallent

2

@Achille Excellent! Przyszedłem tutaj, aby podwójna pozostała dla TinyInt.

Oto częściowo wykonane przypadek przełącznik do konwersji pomiędzy DataTable i 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; 
} 

Łańcuch może być problem, należy zmodyfikować go do swoich potrzeb, ale podwójne powinien pracować co jest pytanie na dłoń.

20

Również, here jest dobrą odpowiedzią na mapowanie typów SQL-CLR z przydatnym wykresem.

Od tego postu (o David): enter image description here