zgi*_*rod 5 t-sql sql-server precision
我有一个sql server精度问题.
我有以下问题:
DECLARE @A numeric(30,10)
DECLARE @B numeric(30,10)
SET @A = 20.225
SET @B = 53.3875
SELECT @A * @B
DECLARE @A1 numeric(30,14)
DECLARE @B1 numeric(30,14)
SET @A1 = 20.225
SET @B1 = 53.3875
SELECT @A1 * @B1
DECLARE @A3 numeric(30,15)
DECLARE @B3 numeric(30,15)
SET @A3 = 20.225
SET @B3 = 53.3875
SELECT @A3 * @B3
DECLARE @A2 numeric(20,15)
DECLARE @B2 numeric(20,15)
SET @A2 = 20.225
SET @B2 = 53.3875
SELECT @A2 * @B2
DECLARE @A4 float
DECLARE @B4 float
SET @A4 = 20.225
SET @B4 = 53.3875
SELECT @A4 * @B4
Run Code Online (Sandbox Code Playgroud)
分别产生以下结果:
1079.762188
1079.762188
1079.7621875
1079.762187500000000000000000000
1079.7621875
正确答案是:1079.7621875.
我不明白为什么,当类型具有相同的签名时,它们会失去精确度.另外,为什么从30,14到30,15会解决精度问题呢?另外,为什么20,15的小数比30,15多得多?
我已经阅读了这篇文章http://msdn.microsoft.com/en-us/library/ms190476(SQL.90).aspx,我想我应该没事,因为我的变量具有相同的精度.
任何帮助将非常感激!
答案在于计算机如何在内部表示数字。根据您使用的精度,SQL Server 将分配 5、9、13 或 17 个字节来表示您的数字(请参阅http://msdn.microsoft.com/en-us/library/ms187746(v=SQL.90)。 aspx)因此,例如,当您从精度 30 移动到精度 20 时,内部表示从 17 字节移动到 13 字节。如何设置 17 字节数字与 13 字节数字的比例,其中较大比例的数字表示专用于比例(15/30 = 0.5、15/20 = 0.75),这会改变舍入行为。没有完美的答案我们拥有的数字类型足以满足大多数应用程序的需要,但有时您会得到像您所看到的奇怪的工件,因为我们在计算机中表示数字的方式有所妥协。
顺便说一句,要非常非常小心浮动类型。它们仅是粗略的近似数字,大量使用时会给出非常错误的结果。当一次计算中使用的浮点数不超过 20 个时,它们对于大多数科学应用来说都是极好的。当大量使用时,假设在 sum(column_name) 中添加 100 万个浮点数,您将得到垃圾。演示如下:
DECLARE @f FLOAT
DECLARE @n NUMERIC(20,10)
DECLARE @i INT
SET @f = 0
SET @n = 0
SET @i = 0
WHILE @i < 1000000
BEGIN
SET @f = @f + 0.00000001
SET @n = @n + 0.00000001
SET @i = @i + 1
END
SELECT @n as [Numeric], @f as [Float]
Run Code Online (Sandbox Code Playgroud)
这给了我关于 SQL Server 2008 的以下答案。
Numeric Float
0.0100000000 0.00999999999994859
Run Code Online (Sandbox Code Playgroud)