我尝试了解在我的方案中在数据库( Sql Server )表中使用真实数据类型的列的影响。我的数据库中有一个真实数据类型的列。 数据是静态的,它始终是0.0,0.1,0.2 ..到1.0范围内的值之一。
使用案例 我必须总结列中的值,并在包含财务数据的一些算术计算中使用总和值。
关注:吗 当我总结列中的值时,它会给我带有更多小数位的结果。
测试
我想总结列值并在乘法和除法计算中使用它。
我想在带有decimal和float数据类型的列中为同一组值重复#1。
过程:我创建了三个不同的表,其中包含一列和相同的值集,但数据类型不同,一个包含十进制,浮点数和实数。并对每个算法进行算术运算。
CREATE TABLE #tReal(d real);
INSERT INTO #tReal
SELECT 0.1 UNION ALL
SELECT 1 UNION ALL
SELECT 1 UNION ALL
SELECT 0.9 UNION ALL
SELECT 1 UNION ALL
SELECT 0.9 UNION ALL
SELECT 1;
select SUM(d) from #tReal
预期成果:5.9
实际结果: 5.8999999538064
并且,如果我对总和执行循环操作,结果是预期的
declare @sumofd real
select @sumofd = SUM(d) from #tReal
select round(@sumofd , 1)
结果:5.9
另外,如果我将数据类型从 真实 更新为 float
CREATE TABLE #tfloat(d float);
INSERT INTO #tfloat
SELECT 0.1 UNION ALL
SELECT 1 UNION ALL
SELECT 1 UNION ALL
SELECT 0.9 UNION ALL
SELECT 1 UNION ALL
SELECT 0.9 UNION ALL
SELECT 1;
select SUM(d) from #tfloat
预期成果:5.9
实际结果: 5.9
而且,如果我将数据类型从 真实 更新为 十进制
,情况也是如此CREATE TABLE #tDecimal(d DECIMAL(3,2));
INSERT INTO #tDecimal
SELECT 0.1 UNION ALL
SELECT 1 UNION ALL
SELECT 1 UNION ALL
SELECT 0.9 UNION ALL
SELECT 1 UNION ALL
SELECT 0.9 UNION ALL
SELECT 1;
select SUM(d) from #tDecimal
预期成果:5.94
实际结果: 5.94
并且,如果我对总和执行一些基本的算术运算,而不是舍入,比如
declare @sumofdReal real
declare @sumofdFloat float
declare @sumofdDecimal decimal(3,2)
select @sumofdReal = SUM(d) from #tReal
select @sumofdFloat = SUM(d) from #tfloat
select @sumofdDecimal = SUM(d) from #tDecimal
乘:
select @sumofdReal * 2
Result: 11.8
select @sumofdFloat * 2
Result: 11.8
select @sumofdDecimal * 2
Result: 11.88
司:
select @sumofdReal / 2
Result: 2.95
select @sumofdFloat / 2
Result: 2.95
select @sumofdDecimal / 2
Result: 2.97000
删除表:
drop table #tReal
drop table #tfloat
drop table #tDecimal
以下是我的问题
是否浮点数和实数类型可以产生精确结果,是否会出现超出舍入错误的任何内容?
答案 0 :(得分:0)
如果您在财务计算中使用这些值,那么您应该(几乎)使用十进制类型,否则您将遇到浮点舍入的问题。当你开始失去便士时,人们会非常伤心。
您可能希望在此处阅读有关浮点运算的更多信息:
十进制类型不受这些限制,应该是准确的。
例如,您最终会遇到尝试将数字舍入为2 DP的情况,例如: 0.695,你可以期望将其上升到0.70。
DECLARE @x REAL = 0.695
SELECT ROUND(@x, 2)
-- outputs 0.69
DECLARE @y DECIMAL(6,4) = 0.695
SELECT ROUND(@y, 2)
-- outputs 0.7000
这是因为你不能准确地将0.695表示为浮点数,而实际上它远远小于0.695。
答案 1 :(得分:0)
使用浮点值总会产生影响,因为它们没有准确表示,并且总会出现一些舍入错误。在将值与常量进行比较时,您必须非常小心,例如: if(a == 0.0)因为如果' a'是数学运算的结果。 Float和Decimal只给你不同的范围和精度。
答案 2 :(得分:0)
real
是float(24)
的同义词,它占用4个字节,最多7位精度。
float
本身与float(53)
相同,double
也与decimal
相同,后者占用8个字节,精度最高可达15位。
在我的场景中,将数据类型设为真实会产生任何影响吗?
可能。 float
,real
和decimal
have different characteristics and are not fully interchangeable。如果要保持精确的十进制表示,请使用具有适当比例和精度的float
数据类型。如果您的数字代表不精确的数据(例如温度,高度,时间或其他"自然"测量无法在没有一些不精确的情况下测量)并且想要更快的数学运算,那么请使用real
(或{{ 1}}如果你不需要超过7位精度。
当我总结列中的值时,它会给我带有更多小数位的结果。
当您添加浮点数时,SQL会确定结果的大小,并使用适当的数据类型。当您添加两个reals
时,结果可能具有超过7位数的精度,因此它可能会使用float
作为结果数据类型。
我是否必须将数据类型更改为float或decimal?为什么呢?
如果精度超过7位数,请使用float
,从小数角度来看,不需要绝对精度,并希望使用浮点类型来加快计算速度。
如果您想要一个固定的比例和精度,并希望最小化浮点数所涉及的不精确度,请使用decimal
。