.net-为什么SQL浮点数与C#不同

嗨,我有一个DataRow从DataSet中抽出DataTable。 我正在访问在SQL中定义为float数据类型的列。 我正在尝试将该值分配给局部变量(C#浮点数据类型),但正在获取InvalidCastExecption

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

现在,我尝试使它起作用,但没有任何意义,感觉不正确。

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

谁能解释我在这里缺少什么?

Keith Sirmons asked 2020-08-01T12:17:03Z
6个解决方案
74 votes

根据SQLDbType的文档,SQL浮点数是double的。

Austin Salonen answered 2020-08-01T12:17:29Z
24 votes

SQL中的浮点数是CLR(C#/ VB)中的Double。 MSDN上有一张SQL数据类型表,其中包含CLR等效项。

bdukes answered 2020-08-01T12:17:49Z
4 votes

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

HLGEM answered 2020-08-01T12:18:09Z
2 votes

Microsoft SQL Server中的浮点数等效于C#中的Double。 这样做的原因是浮点数只能近似为十进制数,浮点数的精度决定了该数字近似十进制数的精度。 Double类型表示双精度64位浮点数,其值范围从负1.79769313486232e308到正1.79769313486232e308,以及正或负零,PositiveInfinity,NegativeInfinity和非a(NaN)。

pdavis answered 2020-08-01T12:18:30Z
0 votes

我认为这里已经回答了主要问题,但是我感到不得不在问题部分添加一些说明该方法可行的内容。

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

这种“有效”的原因和“感觉不正确”的原因是,您在第二次强制转换(左侧的强制转换)时将double降级为float,因此您失去了精度并有效地告诉编译器它 可以截断返回的值。

用这句话说...获取一个对象(在这种情况下恰好持有一个double值)将对象强制转换为double(丢失所有对象包装)将double放入一个float中(失去double的所有精细精度)

例如 如果值是说0.0124022806089461然后执行上述操作,则AccelLimit的值将为0.01240228

因为这就是c#中的float可以从double值中得到的程度。这是一件危险的事情,我很确定它也会被截断而不是四舍五入,但是有人不确定我是否想确认这一点。

David Bridge answered 2020-08-01T12:19:13Z
0 votes

之所以“感觉不正确”,是因为C#使用相同的语法进行装箱和转换,这是两个非常不同的方面。 (double)(float)object_var包含一个装箱为对象的双精度值。 需要(double)将对象拆箱成两倍。 然后在其前面的(float)将双精度类型转换为浮点值。 C#不允许在同一操作中进行装箱和投射,因此您必须先拆箱然后进行投射。

即使强制转换是非破坏性的,也是如此。 如果将浮动对象装箱为您想要转换为双精度对象的对象,则可以这样做:(double)(float)object_var

dubrowgn answered 2020-08-01T12:19:40Z
translate from https://stackoverflow.com:/questions/122523/why-is-a-sql-float-different-from-a-c-sharp-float