Howdy, I have a DataRow pulled out of a DataTable from a DataSet. I am accessing a column that is defined in SQL as a float datatype. I am trying to assign that value to
A float in SQL is a Double in the CLR (C#/VB). There's a table of SQL data types with the CLR equivalents on MSDN.
The float in Microsoft SQL Server is equivalent to a Double in C#. The reason for this is that a floating-point number can only approximate a decimal number, the precision of a floating-point number determines how accurately that number approximates a decimal number. The Double type represents a double-precision 64-bit floating-point number with values ranging from negative 1.79769313486232e308 to positive 1.79769313486232e308, as well as positive or negative zero, PositiveInfinity, NegativeInfinity, and Not-a-Number (NaN).
The reason it "doesn't feel right" is because C# uses the same syntax for unboxing and for casting, which are two very different things. exercise["DefaultAccelLimit"]
contains a double value, boxed as an object. (double)
is required to unbox the object back into a double. The (float)
in front of that then casts the double to a float value. C# does not allow boxing and casting in the same operation, so you must unbox, then cast.
The same is true even if the cast is nondestructive. If a float was boxed as an object that you wanted to cast into a double, you would do it like so: (double)(float)object_var
.
I think the main question has been answered here but I feel compelled to add something for the section of the question that states that this works.
_AccelLimit = (float)(double)exercise["DefaultAccelLimit"];
The reason this "works" and the reason it "doesn't feel right" is that you are downgrading the double to a float by the second cast (the one on the left) so you are losing precision and effectively telling the compiler that it is ok to truncate the value returned.
In words this line states... Get an object (that happens to hold a double in this case) Cast the object in to a double (losing all the object wrapping) Cast the double in to a float (losing all the fine precision of a double)
e.g. If the value is say 0.0124022806089461 and you do the above then the value of AccelLimit will be 0.01240228
as that is the extent of what a float in c# can get from the double value. Its a dangerous thing to do and I am pretty sure its a truncation too rather than a rounding but someone may want to confirm this as I am not sure.
A SQL float is a double according to the documentation for SQLDbType.
And normally you would never want to use float in SQL Server (or real) if you plan to perform math calculations on the data as it is an inexact datatype and it will introduce calculation errors. Use a decimal datatype instead if you need precision.