我正在导入一个文本文件,其中包含一个数字最多为千分之一的字段作为数字字段。我正在运行并更新查询以修复SSN(前面的零)并从数字字段中减去500.
UPDATE CODImportFile
SET CODImportFile.[Original SSN] = Format([Original SSN],"000000000")
, CODImportFile.[Lifetime Eligibility Used] = [Lifetime Eligibility Used]-500;
我不知道为什么,但有些结果看起来像这样:
Original:500.016
Result: 1.60000000000196E-02
知道可能导致这种情况的原因是什么?
答案 0 :(得分:2)
由于[Lifetime Eligibility Used]
的数据类型为double,因此查询中的计算与此类似:
SELECT
CDbl(500.016) - 500 AS difference,
TypeName(CDbl(500.016)-500) AS data_type;
...返回此信息:
difference data_type
1.60000000000196E-02 Double
这些意外的小数位是二进制系统中十进制数学固有的不精确的人为因素。您可以将字段类型转换为单个(或在计算中将double转换为单个),但是您仍然可以获得“额外”小数位...只是这些小数位的一组不同的值。
我认为你应该丢弃你不想存储的任何小数位。
UPDATE CODImportFile
SET [Lifetime Eligibility Used] =
Round([Lifetime Eligibility Used]-500, 3);
然后你只需要决定你想要的舍入方法。
? Round(0.1245, 3)
0.124
? CDbl(Format(0.1245, "0.000"))
0.125
答案 1 :(得分:0)
这可能是由于SQL将数字视为二进制,当您期望十进制结果时:某些小数部分无法表示为二进制而没有舍入错误。例如,.1无法准确表示。
请参阅 Why can't decimal numbers be represented exactly in binary?获取更多信息。
答案 2 :(得分:0)
从原始数字减去500(~0.016)后,结果是“正确”的余数。浮点数无论如何都不准确,这就是为什么你最后有...00196
的原因。您应该能够通过在十进制字段中指定适当的比例(在这种情况下可能为3)以及精度来解决此问题。
来自http://msdn.microsoft.com/en-us/library/aa258832(v=sql.80).aspx:
十进制[(p [,s])]和数字[(p [,s])]
修正了精度和刻度数。当使用最大精度时,有效值为 - 10 ^ 38 +1到10 ^ 38 - 1.十进制的SQL-92同义词是dec和dec(p,s)。
p(精度)
指定小数点左侧和右侧可存储的最大小数位数。精度必须是从1到最大精度的值。最大精度为38.默认精度为18。
s(规模)
指定可以存储在小数点右侧的最大小数位数。比例必须是从0到p的值。只有在指定精度时才能指定比例。默认比例为0;因此,0 <= s <= p。最大存储大小因精度而异。