SQL Server精确度疯狂 [英] Sql Server Precision Crazyness

查看:104
本文介绍了SQL Server精确度疯狂的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用sql server精度时遇到问题.

I am having an issue with sql server precision.

我有以下查询:

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

分别产生以下结果:

1079.762188

1079.762188

1079.762188

1079.762188

1079.7621875

1079.7621875

1079.762187500000000000000000000

1079.762187500000000000000000000

1079.7621875

1079.7621875

正确的答案是:1079.7621875.

The correct answer is: 1079.7621875.

我不明白为什么,当类型具有相同的签名时,它们将失去精度.另外,为什么从30,14变为30,15可以解决精度问题?还有,为什么20,15的小数位数比30,15小得多?

I do not understand why, when the types have the same signature they are losing precision. Also, why does going from 30,14 to 30,15 fix the precision problem? Also, why does 20,15 have so many more decimals than 30,15?

我已阅读本文 http://msdn. microsoft.com/en-us/library/ms190476(SQL.90).aspx ,我认为应该没问题,因为我的变量具有相同的精度.

I have read this article http://msdn.microsoft.com/en-us/library/ms190476(SQL.90).aspx and I think I should be fine because my variables have the same precision.

任何帮助将不胜感激!

推荐答案

答案在于计算机如何在内部表示数字.根据您使用的精度,SQL Server将分配5、9、13或17个字节来表示您的数字(请参见

The answer lies in how computers represent numbers internally. Depending on the precision you use, SQL Server will allocate 5, 9, 13 or 17 bytes to represent your number (see http://msdn.microsoft.com/en-us/library/ms187746(v=SQL.90).aspx) So, for example when you moved from precision 30 to precision 20, the internal representation moved from 17 bytes to 13 bytes. How you set the scale on a 17 byte number versus a 13 byte number where a greater proportion of the number representation is dedicated to scale (15/30 = 0.5, 15/20 = 0.75, changes the rounding behavior. There is no perfect answer. The number types we have are good enough for most applications but sometimes you'll get strange artifacts like you're seeing due to the way we've compromised in representing numbers in computers.

顺便说一句,要非常小心浮点类型.它们仅粗略地近似于数字,并且在数量上使用时,会给您非常错误的结果.当一次计算中使用的浮点数不超过20个时,它们对于大多数科学应用而言都是极好的.当大量使用时,假设在sum(column_name)中添加一百万个浮点数,您将得到垃圾.下面的演示:

As an aside, be very, very careful of float types. They only roughly approximate numbers and will give you very wrong results when used in quantity. They are superb for most scientific applications when no more than about 20 floating point numbers are used in one calculation. When used in quantity, say adding 1 million floating point numbers in a sum(column_name) you will get garbage. Demonstration below:

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]

这为我在SQL Server 2008上提供了以下答案.

This gives me the following answer on SQL Server 2008.

Numeric      Float
0.0100000000    0.00999999999994859

这篇关于SQL Server精确度疯狂的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆