2

我有一个代表特定数据库表的类。该类中的某些属性以及数据库表中的某些字段是双精度类型。

在这里,在课堂上,您会看到一些属性具有 1 个有效数字,例如。T12、T13、T18、T19(0.8、12.1 等)。

类视图

但是,当我执行将此类插入数据库表时,Linq2Db会产生这样的查询:

查询视图

当我查看数据库表时,字段包含正确的一位有效数字值:

数据库表视图

我完全知道浮点数是如何以二进制格式表示的。我已经阅读文章为什么浮点数不准确?.

我的问题:

  1. 为什么类中的双重类型表示(T12 = -0.8)与“Linq2Db”操作后的表示不同(T12 = -0.800...004)?

  2. 在数据库中保存这样的双重值是否安全?(我想防止值不准确)

  3. 为什么查询中的值和数据库表中的值之间存在差异?

编辑1:

这是数据库查询的结果。15 位有效数字(全 0)与 17 位有效数字(上图)。Access 不能显示超过 15 位数字。

查询数据库

编辑2:

Decimal               0.8
Class Double          0.8
Floating-Point Double 0.8000000000000000444089209850062616169452667236328125
Floating-Point Single 0.800000011920928955078125 (for comparison)
SQL Query             0.80000000000000004 (!)  => 17 digits after point (why?)
MS Access             0.800000000000000 = 0.8  => 15 digits after point

为什么类中的双精度类型可以是 0.8,但是没有任何操作或算术运算的相同值插入到数据库中为 0.80000000000000004?'Linq2Db' 用它做什么?

4

2 回答 2

2

linq2db 使用 17 位有效数字将双精度值表示为十进制 SQL 文字,因为它是允许您将双精度值往返转换为十进制表示并安全返回而不会丢失精度的最小位数。

在您的情况下,没有必要,因为 Access(和 Excel BTW)不支持超过 15 个有效数字的双精度类型。

于 2018-11-18T15:00:54.350 回答
1

如果您想要精确表示十进制值,请切换到decimal浮点表示而不是浮点表示。

像 0.8 这样的数字无法使用固定数量的二进制十进制数字精确表示(但是,0.5 和 0.75 可以)。您实际看到的取决于显示结果的应用程序,而不是它的存储方式。

因此,只需使用与您真正想要的数据类型相对应的数据类型,即定点小数。

于 2018-05-03T13:05:06.560 回答