【问题标题】:Why is a SQL float different from a C# float为什么 SQL 浮点数与 C# 浮点数不同
【发布时间】:2010-09-12 11:01:15
【问题描述】:

您好,我从 DataSet 中的 DataTable 中提取了一个 DataRow。我正在访问在 SQL 中定义为浮点数据类型的列。我正在尝试将该值分配给局部变量(c# float 数据类型),但得到一个 InvalidCastExecption

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

现在,玩弄这个我确实让它工作了,但它没有任何意义,而且感觉不对。

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

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

【问题讨论】:

    标签: c# .net sql casting dataset


    【解决方案1】:

    它“感觉不对”的原因是因为 C# 对 unboxingcasting 使用相同的语法,这是两个非常不同的东西。 exercise["DefaultAccelLimit"] 包含一个双精度值,被装箱为一个对象。需要(double) 才能将对象拆箱重新转换为双精度对象。前面的 (float) 然后 casts 将双精度值转换为浮点值。 C# 不允许在同一操作中进行装箱和强制转换,因此必须先取消装箱,然后再进行强制转换。

    即使演员表是非破坏性的也是如此。如果将浮点数装箱为要转换为双精度的对象,则可以这样做:(double)(float)object_var

    【讨论】:

      【解决方案2】:

      我认为这里已经回答了主要问题,但我觉得有必要为问题的部分添加一些内容,说明这有效。

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

      这个“有效”的原因和它“感觉不对”的原因是你在第二次演员(左边的那个)之前将双精度降级为浮点数,所以你正在失去精度并有效地告诉编译器认为可以截断返回的值。

      一句话,这行表明...... 获取一个对象(在这种情况下恰好包含一个双精度对象) 将对象转换为双精度(丢失所有对象包装) 将双精度转换为浮点数(失去双精度的所有精细精度)

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

      因为这是 c# 中的浮点数可以从双精度值中获得的程度。 这是一件危险的事情,我很确定它也是截断而不是四舍五入,但有人可能想确认这一点,因为我不确定。

      【讨论】:

        【解决方案3】:

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

        【讨论】:

        • 大多数数学和工程计算都可以。现在,财务和会计计算当然是不同的。
        【解决方案4】:

        Microsoft SQL Server 中的浮点数相当于 C# 中的 Double。原因是浮点数只能逼近十进制数,浮点数的精度决定了该数字逼近十进制数的准确程度。 Double 类型表示双精度 64 位浮点数,其值范围从负 1.79769313486232e308 到正 1.79769313486232e308,以及正或负零、PositiveInfinity、NegativeInfinity 和 Not-a-Number (NaN)。

        【讨论】:

          【解决方案5】:

          SQL 中的浮点数是 CLR (C#/VB) 中的 Double。 MSDN 上有a table of SQL data types with the CLR equivalents

          【讨论】:

          • 它们相似但肯定不等价。根据 IEEE 规范,Double 支持 +Infinity、-Infinity 和 NaN 的值,但 SQL float 绝对不支持。并会抛出溢出错误。希望 MSDN 将其添加到他们的信息页面。
          • 好的。那么你的答案是什么?
          【解决方案6】:

          根据 the documentation for SQLDbType,SQL 浮点数是双精度。

          【讨论】:

          • 它们相似但肯定不等价。根据 IEEE 规范,Double 支持 +Infinity、-Infinity 和 NaN 的值,但 SQL float 绝对不支持。并且会抛出溢出错误。
          • 我同意 Alain May 的 cmets,但我还不明白为什么。我见过 .net double 表示会破坏 SQL 浮点数的情况。示例包括无穷大值和某些接近零的负指数。我怀疑 MS 针对存储效率进行了优化。
          • @RaoulRubin:见MSDN documentation for TSQL floats。他们从未提及 IEEE 合规性,并声明它遵循一些未命名的 ISO 标准。快速搜索会得到 ISO/IEC 10967,它声明它与 IEEE 754 兼容,但不能保证完全实现。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-01-31
          • 2017-11-16
          • 2019-11-28
          • 2019-07-08
          • 2018-11-30
          相关资源
          最近更新 更多