自动小数舍入问题

Kah*_*ahn 11 sql-server-2008 sql-server decimal

问题比较简单。我需要计算 3 列,其中中间结果是大数,并且我在早期遇到问题,SQL Server 基本上四舍五入,无论是否进行任何强制转换/转换。

例如,让我们做一个简单的除法 1234/1233。计算器将产生 1,00081103000811。但是当我在 SQL Server 上执行此操作时,我们得到以下信息:

-- Result: rounded at 1.000811000... with trailing zeroes up until the 37 precision
SELECT CAST(CAST(1234 AS DEC(38,34))/CAST(1233 AS DEC(38,34)) AS DEC(38,37))

-- Result: rounded at 1.000811
SELECT CONVERT(DECIMAL(38,32), 1234)/CONVERT(DECIMAL(38,32),1233)

-- Correct result at 1,00081103000811
-- But this requires the zeroes to be put in manually when you don't
-- even know the precision of the end result
SELECT 1234.0/1233.00000000000000
Run Code Online (Sandbox Code Playgroud)

为什么会发生这种自动舍入?当您无法确定一个数字(int 或 dec 部分)有多大时,计算超长十进制值的最佳方法是什么,因为该表可以包含各种不同的值?

谢谢!

gbn*_*gbn 17

tl;博士

不要用 SQL 语言进行计算

更长

结果规模和精度在 MSDN 上有很好的定义。这不直观,真的。然而,简单来说,当输入比例高时,精度会丢失,因为结果比例需要下降到 38 并匹配精度下降。

确认事情

  • 第一个示例中的额外 CAST 只需添加零
  • 根据我的 MSDN 链接(第二个示例)发生截断
  • 带有常量的第三个示例隐含了刚好足够的十进制值 (5,1) 和 18,14)。
    这意味着结果比例和精度没有截断(见blow)

更多关于第 1 和第 3 种情况..

除法的结果比例为max(6, s1 + p2 + 1)

  • 第一个例子,这是 77,它下降到 38。精度也被类似地强制降低,最小为 6(见这个
  • 第三个例子,这是 24 所以精度不需要调整

你有一些选择

  • 在客户端代码中计算,例如 .net
  • 使用 CLR 函数进行 .net 计算
  • 生活在准确性的损失中
  • 使用浮点数并以 15 位有效数字为最佳

最后,请参阅 SO /sf/ask/29674781/#424052