double 类型 属性(class)和 double 类型字段(SQL 查询)中浮点数表示的差异
Difference in represtantion of floating point number in double type property (class) and in double type field (SQL query)
我有一个 class 代表特定的数据库 table。此 class 中的某些属性以及数据库 table 中的某些字段是双精度类型。
在这里,在 class 中,您会看到一些属性有 1 个有效数字,例如。 T12、T13、T18、T19(0.8、12.1 等)。
然而,当我执行将此 class 插入数据库 table 时,Linq2Db
会产生这样的查询:
当我查看数据库 table 时,字段包含正确的一位有效数字值:
我完全知道浮点数是如何用二进制格式表示的。我已经读过文章 Why Are Floating Point Numbers Inaccurate?.
我的问题:
为什么 class 中的双重类型表示 (T12 = -0.8) 与 'Linq2Db' 操作后的表示不同 (T12 = -0.800...004)?
在数据库中保存这样的双精度值安全吗? (我想防止有不准确的值)
为什么查询中的值与数据库中的值不同table?
编辑 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
为什么class中的double类型可以是0.8,但没有任何操作或算术运算的相同值被插入到数据库中作为0.80000000000000004? 'Linq2Db' 用它做什么?
如果您想要精确表示十进制值,请切换到 decimal
而不是浮点表示法。
像 0.8 这样的数字 不能 使用固定数量的二进制十进制数字来准确表示(但是,0.5 和 0.75 可以)。您实际看到的内容取决于显示结果的应用程序,而不是结果的存储方式。
因此,只需使用与您真正想要的数据类型相对应的定点小数。
linq2db 使用 17 位有效数字将双精度值表示为十进制 SQL 文字,因为它是允许您将双精度值往返十进制表示并安全返回而不会丢失精度的最少位数。
在您的情况下没有必要,因为 Access(和 Excel 顺便说一句)不支持 double 类型超过 15 个有效数字。
我有一个 class 代表特定的数据库 table。此 class 中的某些属性以及数据库 table 中的某些字段是双精度类型。
在这里,在 class 中,您会看到一些属性有 1 个有效数字,例如。 T12、T13、T18、T19(0.8、12.1 等)。
然而,当我执行将此 class 插入数据库 table 时,Linq2Db
会产生这样的查询:
当我查看数据库 table 时,字段包含正确的一位有效数字值:
我完全知道浮点数是如何用二进制格式表示的。我已经读过文章 Why Are Floating Point Numbers Inaccurate?.
我的问题:
为什么 class 中的双重类型表示 (T12 = -0.8) 与 'Linq2Db' 操作后的表示不同 (T12 = -0.800...004)?
在数据库中保存这样的双精度值安全吗? (我想防止有不准确的值)
为什么查询中的值与数据库中的值不同table?
编辑 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
为什么class中的double类型可以是0.8,但没有任何操作或算术运算的相同值被插入到数据库中作为0.80000000000000004? 'Linq2Db' 用它做什么?
如果您想要精确表示十进制值,请切换到 decimal
而不是浮点表示法。
像 0.8 这样的数字 不能 使用固定数量的二进制十进制数字来准确表示(但是,0.5 和 0.75 可以)。您实际看到的内容取决于显示结果的应用程序,而不是结果的存储方式。
因此,只需使用与您真正想要的数据类型相对应的定点小数。
linq2db 使用 17 位有效数字将双精度值表示为十进制 SQL 文字,因为它是允许您将双精度值往返十进制表示并安全返回而不会丢失精度的最少位数。
在您的情况下没有必要,因为 Access(和 Excel 顺便说一句)不支持 double 类型超过 15 个有效数字。