it-swarm-eu.dev

Proč je SQL float odlišný od C # float

Ahoj, mám DataRow vytáhl z DataTable z DataSet. Mám přístup ke sloupci, který je definován v SQL jako datový typ float. Snažím se tuto hodnotu přiřadit lokální proměnné (c # float datatype), ale dostávám InvalidCastExecption 

DataRow exercise = _exerciseDataSet.Exercise.FindByExerciseID(65);
_AccelLimit = (float)exercise["DefaultAccelLimit"];  

Hrál jsem si s tím, že to fungovalo, ale nedávalo to smysl a necítilo se to dobře. 

_AccelLimit = (float)(double)exercise["DefaultAccelLimit"];

Může někdo vysvětlit, co mi chybí?

40
Keith Sirmons

SQL float je dvojitá podle dokumentace pro SQLDbType .

69
Austin Salonen

Float v SQL je Double v CLR (C #/VB). Existuje tabulka datových typů SQL s ekvivalenty CLR na MSDN.

24
bdukes

A normálně byste nikdy nechtěli použít float v SQL Serveru (nebo reálném), pokud plánujete provádět matematické výpočty na datech, protože se jedná o nepřesný datový typ a zavede chyby výpočtu. Pokud potřebujete přesnost, použijte místo toho desetinný datový typ.

3
HLGEM

Plovoucí v Microsoft SQL Server je ekvivalentní dvojité v C #. Důvodem je to, že číslo s plovoucí desetinnou čárkou se může přibližovat pouze desetinnému číslu, přesnost čísla s plovoucí desetinnou čárkou určuje, jak přesně toto číslo aproximuje desetinné číslo. Typ Double představuje 64bitové číslo s dvojitou přesností s plovoucí desetinnou čárkou s hodnotami v rozmezí od záporných 1,79769313486232e308 do kladných 1,79769313486232e308, stejně jako kladných nebo záporných nula, positivních nekonečných hodnot, negativní nekonečno a ne-číselných čísel (NaN). 

2
pdavis

Důvod, proč se "necítí dobře" je, že C # používá stejnou syntaxi pro unboxing a pro casting , což jsou dvě velmi odlišné věci. exercise["DefaultAccelLimit"] obsahuje dvojitou hodnotu v rámečku jako objekt. (double) je vyžadováno pro odemknutí objektu zpět do dvojité. (float) před tím pak vrhá dvojité na hodnotu float. C # neumožňuje boxování a odlévání ve stejné operaci, takže musíte odemknout, pak odlit.

Totéž platí, i když je obsazení nedestruktivní. Pokud byl float v krabici jako objekt, který jste chtěli přenést do dvojité, udělali byste to takto: (double)(float)object_var.

0
dubrowgn

Myslím, že hlavní otázka byla zodpovězena zde, ale cítím se nucen přidat něco do části otázky, která uvádí, že to funguje.

_AccelLimit = (float) (double) cvičení ["DefaultAccelLimit"];

Důvodem tohoto "funguje" a důvod, proč "necítí dobře" je to, že snižujete dvojnásobek na plovák druhým obsazením (ten na levé straně), takže ztrácíte přesnost a efektivně říkáte kompilátoru, že je v pořádku zkrátit vrácenou hodnotu.

Ve slově tento řádek uvádí ... Získat objekt (v tomto případě se stane, že v tomto případě drží dvojici) Přeneste objekt do dvojité (ztrácí všechny obtékání objektů) Obsazení double do float (ztráta všech jemných přesností dvojité)

např. Pokud je hodnota říci 0.0124022806089461 A vy výše uvedené pak hodnota AccelLimit bude 0.01240228

to je rozsah toho, co může float v c # získat z dvojité hodnoty. Je to nebezpečná věc a já jsem si jistý, že je to také zkrácení spíše než zaokrouhlování, ale někdo to může chtít potvrdit jako Nejsem si jistý.

0
David Bridge