我正在做这个小练习。
declare @No decimal(38,5);
set @No=12345678910111213.14151;
select @No*1000/1000,@No/1000*1000,@No;
结果是:
12345678910111213.141510
12345678910111213.141000
12345678910111213.14151
为什么前2个的结果在数学上选择不同它应该是相同的?
答案 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