Sql server为相同的数学计算提供不同的结果
步骤1 查询:Sql server为相同的数学计算提供不同的结果,sql,sql-server,Sql,Sql Server,步骤1 查询: SELECT (ISNULL(TRY_CONVERT(NUMERIC(38, 14), '123456789.34554563453524'), 0) * ISNULL(try_convert(NUMERIC(38, 14), '456789876.34556345345353'), 0))/100.0 结果: 563938115391720.660302 步骤2 我已将上述查询修改为: SELECT (123456789.34554563453524 * 456789
SELECT
(ISNULL(TRY_CONVERT(NUMERIC(38, 14), '123456789.34554563453524'), 0)
*
ISNULL(try_convert(NUMERIC(38, 14), '456789876.34556345345353'), 0))/100.0
结果:
563938115391720.660302
步骤2
我已将上述查询修改为:
SELECT (123456789.34554563453524 * 456789876.34556345345353) / 100.0
但结果是:
563938115391720.660302253145411988
这里,Step1查询结果在某个点截断了小数
如何重新写入它以获得我为Step2查询得到的确切数字(563938115391720.660302253145411988)。这与十进制精度所预测的完全一样。 看 。不要漂浮。在这种情况下,
decimal(23,14)
在第一个示例中,它们是decimal(38,14)
当使用相同的精度并显式转换为相同的数据类型时,结果相同
SELECT
(ISNULL(TRY_CONVERT(NUMERIC(23, 14), '123456789.34554563453524'), 0)
*
ISNULL(try_convert(NUMERIC(23, 14), '456789876.34556345345353'), 0))/100.0
563938115391720.660302253145411988
注意,100.0
在这种情况下也是十进制(4,1)
最后一句话:由于乘法中38/23的差异,在一些精度变化后我不会将其标记为重复,但我认为这可能解释了您的观察结果。最多只有48位精度可用,您的产品可能会超过此限制。浮点舍入误差在所有编程语言中都是一个已知的问题。实际需要该精度的可能性接近于零。如果你把它四舍五入,它实际上可能是零。请注意,SQL Server没有任意精度的数据类型,因此无论您使用哪种类型的数据,总会有一些计算会导致精度降低,即使这种计算碰巧是可能的。如果你只是想解释差异,那很好,但不要误导自己,认为在所有情况下都可以得到精确的结果。@TimBiegeleisen数字都是十进制的,而不是浮点的。这就是SQL Server解释literals@TimBiegeleisen的方式假设SQL Server将未转换的十进制值(如“100.1”)隐式转换为浮点值,我尝试了OP的第一个查询的一个变体,其中我将100.0转换为数字,并得到了相同的结果。我甚至删除了ISNULL和除以100.0,它仍然截断了十进制,所以我认为这证明浮点精度不是一个因素。