为什么SQL浮点数不同于C#float

你好,我有一个DataRow从DataSet的DataTable中拉出。 我正在访问一个在SQL中定义为浮点数据types的列。 我试图将该值分配给本地variables(C#浮点数据types),但得到一个InvalidCastExecption

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

现在,玩了这个,我确实做到了,但没有任何意义,感觉不对。

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

任何人都可以解释我在这里失踪?

根据SQLDbType的文档, SQL float是double。

SQL中的float是CLR中的Double (C#/ VB)。 有一个SQL数据types的表与 MSDN 上的CLR等价物 。

Microsoft SQL Server中的float等效于C#中的Double。 原因是浮点数只能接近十进制数,浮点数的精度决定了该数的精确度接近十进制数。 Doubletypes表示一个双精度64位浮点数,其值从负1.79769313486232e308到正1.79769313486232e308,以及正或负零,PositiveInfinity,NegativeInfinity和非数字(NaN)。

通常,如果您计划对数据执行math计算,通常您不希望在SQL Server中使用float(或实数),因为它是不精确的数据types,并且会引入计算错误。 如果您需要精确度,请使用十进制数据types。

我认为主要的问题已经在这里得到解答,但是我觉得不得不在这个问题的部分增加一些说明这一点的工作。

_AccelLimit =(float)(double)exercise [“DefaultAccelLimit”];

这个“起作用”的原因以及“感觉不对”的原因是你将第二个types的variables(左边的那个)降级为float,所以你正在失去精度,并且有效地告诉编译器:可以截断返回的值。

换句话说,这一行指出…得到一个对象(在这种情况下碰巧保持一个double)将对象转换为double(丢失所有对象的包装)将double转换为一个float(失去所有的精度双)

例如,如果值是0.0124022806089461,并且您执行了上述操作,那么AccelLimit的值将是0.01240228

因为这是c#中的float值可以从double值得到的程度。 这是一个危险的事情,我敢肯定它是一个截断,而不是一个舍入,但有人可能要确认这一点,因为我不知道。

“不正确”的原因是因为C#使用相同的语法拆箱铸造 ,这是两个非常不同的东西。 exercise["DefaultAccelLimit"]包含一个double值,作为一个对象装箱。 (double)是需要解开对象回到一个双。 然后在它前面的(float)将double转换为float值。 C#不允许在同一个操作中进行装箱和投射,所以你必须解开盒子然后投射。

即使演员是无损的,情况也是如此。 如果一个浮动框被作为一个对象,你想投入一个双,你会这样做: (double)(float)object_var