1

我正在导入一个文本文件,其中包含一个数字高达千位小数的字段作为数字字段。然后我运行并更新查询以修复 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 

知道是什么原因造成的吗?

4

3 回答 3

2

由于 的数据类型[Lifetime Eligibility Used]是双精度的,因此查询中的计算类似于:

SELECT
    CDbl(500.016) - 500 AS difference,
    TypeName(CDbl(500.016)-500) AS data_type;

...返回这个:

difference           data_type
1.60000000000196E-02 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
于 2012-10-11T16:42:10.027 回答
0

这可能是由于 SQL 将数字视为二进制而导致的,而您期望得到十进制结果:某些十进制分数不能表示为二进制而不会出现舍入错误。例如,.1 不能准确表示。

请参阅 为什么不能用二进制精确表示十进制数?了解更多信息。

于 2012-10-11T15:07:45.470 回答
0

从原始数字(~0.016)中减去 500 后的结果是“正确的”余数。无论如何,浮点数并不精确,这就是为什么...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。

小号(规模)

指定可以存储在小数点右侧的最大小数位数。比例必须是从 0 到 p 的值。仅当指定精度时才能指定比例。默认比例为 0;因此,0 <= s <= p。最大存储大小因精度而异。

于 2012-10-11T15:21:25.060 回答