为什么十进制表现不同?

时间:2010-04-12 13:17:24

标签: sql sql-server sql-server-2005 tsql

我正在做这个小练习。

declare @No decimal(38,5);
set @No=12345678910111213.14151;

select @No*1000/1000,@No/1000*1000,@No;

结果是:

12345678910111213.141510    
12345678910111213.141000    
12345678910111213.14151

为什么前2个的结果在数学上选择不同它应该是相同的?

7 个答案:

答案 0 :(得分:2)

由于四舍五入,第二个sql首先除以1000,即12345678910111.21314151,但是你的小数只有38,5,所以你丢失了最后三个小数点。

答案 1 :(得分:2)

因为当你先分开时,你得到:

12345678910111.21314151

然后在点之后只剩下六位小数:

12345678910111.213141

然后* 1000

12345678910111213.141

答案 2 :(得分:2)

它不会做代数将1000/1000转换为1. 它实际上将遵循操作的顺序并执行每一步。

@No*1000/1000
 yields:  @No*1000  =  12345678910111213141.51000
          then /1000=  12345678910111213.141510

    @No/1000*1000
yields:  @No/1000  = 12345678910111.213141
         then *1000= 12345678910111213.141000

首先划分你丢失十进制数字。

答案 3 :(得分:1)

因为中间类型与参数相同 - 在本例中为decimal(38,5)。因此,首先划分会使您在截断的答案中反映出精确度的损失。首先乘以1000不会给出任何精度损失,因为它不会超载38位数。

答案 4 :(得分:1)

这可能是因为你首先丢失了部分数据。请注意,@No具有5点小数精度,因此当您将此数字除以1000时,您突然需要8位小数部分:

123.12345 / 1000 = 0.12312345

因此必须对值进行舍入(0.12312),然后将此值乘以1000 - > 123.12(您丢失了0.00345

我认为这就是结果的原因......

答案 5 :(得分:0)

第一个@No*1000然后将它除以1000.中间值始终能够代表所有小数位。第二个表达式首先除以1000,抛出最后两位小数,然后再乘以原始值。

答案 6 :(得分:0)

您可以通过对表达式中的第一个值使用CONVERT或CAST来解决此问题,以增加小数位数并避免精度损失。

DECLARE @num decimal(38,5)
SET @num = 12345678910111213.14151

SELECT CAST(@num AS decimal(38,8)) / 1000 * 1000