it-swarm.com.de

Warum unterscheidet sich ein SQL-Float von einem C # -Float?

Wie auch immer, ich habe eine DataRow aus einer DataTable aus einem DataSet gezogen. Ich greife auf eine Spalte zu, die in SQL als Float-Datentyp definiert ist. Ich versuche, diesen Wert einer lokalen Variablen (c # float-Datentyp) zuzuweisen, erhalte jedoch eine InvalidCastExecption 

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

Jetzt habe ich damit rumgespielt, aber es machte keinen Sinn und es fühlte sich nicht richtig an. 

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

Kann jemand erklären, was mir hier fehlt?

40
Keith Sirmons

Ein SQL-Float ist ein Double gemäß der Dokumentation zu SQLDbType .

69
Austin Salonen

Ein Float in SQL ist ein Double in der CLR (C #/VB). Es gibt eine Tabelle von SQL-Datentypen mit den CLR-Entsprechungen auf MSDN.

24
bdukes

Normalerweise würden Sie niemals Float in SQL Server (oder Real) verwenden wollen, wenn Sie mathematische Berechnungen der Daten durchführen möchten, da dies ein ungenauer Datentyp ist und Berechnungsfehler auftreten. Verwenden Sie stattdessen einen dezimalen Datentyp, wenn Sie Genauigkeit benötigen.

3
HLGEM

Der Float in Microsoft SQL Server entspricht einem Double in C #. Der Grund dafür ist, dass eine Gleitkommazahl nur eine Dezimalzahl approximieren kann. Die Genauigkeit einer Gleitkommazahl bestimmt, wie genau diese Zahl approximiert eine Dezimalzahl ist. Der Double-Typ repräsentiert eine 64-Bit-Gleitkommazahl mit doppelter Genauigkeit mit Werten im Bereich von negativ 1.79769313486232e308 bis positiv 1.79769313486232e308 sowie positive oder negative Null, PositiveInfinity, NegativeInfinity und Not-a-Number (NaN). 

2
pdavis

Der Grund, warum es sich "nicht richtig anfühlt", ist, dass C # dieselbe Syntax für unboxing und für casting verwendet. exercise["DefaultAccelLimit"] enthält einen doppelten Wert, der als Objekt eingeschlossen ist. (double) ist erforderlich, um unbox das Objekt wieder in ein Double zu packen. Der (float) vor dem dann wandelt das Double in einen Float-Wert um. In C # ist das Boxen und Casting nicht in derselben Operation zulässig. Sie müssen also die Box auspacken und dann casten.

Das Gleiche gilt, auch wenn die Besetzung nicht destruktiv ist. Wenn ein Float als Objekt in ein Doppelkästchen gesetzt wurde, würden Sie dies wie folgt tun: (double)(float)object_var.

0
dubrowgn

Ich denke, die Hauptfrage wurde hier beantwortet, aber ich fühle mich gezwungen, etwas für den Abschnitt der Frage hinzuzufügen, der besagt, dass dies funktioniert.

_AccelLimit = (float) (double) Übung ["DefaultAccelLimit"];

Der Grund, warum dies "funktioniert" und der Grund, warum es sich "nicht richtig anfühlt", besteht darin, dass Sie das Double mit dem zweiten Cast (dem linken Cast) zu einem Float-Wert herabstufen, sodass Sie an Präzision verlieren und dem Compiler effektiv mitteilen, dass er es macht ist in Ordnung, um den zurückgegebenen Wert abzuschneiden.

In Wörtern in dieser Zeile heißt es ... Holen Sie sich ein Objekt (das in diesem Fall ein Double enthält) Das Objekt in ein Double umwandeln (wobei alle Objektumbrüche verloren gehen) Cast das Double in ein Schwimmer (verliert alle Feinheiten eines Doppelten)

z.B. Wenn der Wert sagen soll 0.0124022806089461 Und wenn Sie dies tun, wird der Wert von AccelLimit 0.01240228 sein

da dies das Ausmaß ist, was ein Float in c # aus dem doppelten Wert erhalten kann .. Es ist eine gefährliche Sache und ich bin mir ziemlich sicher, dass es eine Verkürzung ist und keine Rundung, aber jemand möchte dies so bestätigen, wie ich bin nicht sicher.

0
David Bridge