我们正在使用我们的工具进行迁移。我们表中的一些数据类型已从real更改为float。要了解我已经运行以下代码的影响:
declare @realVariable as real,
@floatVariable as float
set @realVariable=152304.11999512
set @floatVariable=152304.11999512
select cast(@realVariable AS decimal(15, 4)) as realcol,str(@floatVariable,15,4) as floatcol
real变量和float变量的结果不同: 真正= 152304.1250 float = 152304.1200
如何确保浮动结果与实际相同?
答案 0 :(得分:1)
float和real都是浮点数值数据的近似数字数据类型。
real与float(24)相同。如果声明没有后缀的float,则表示float(53)。
因此,您将从real(浮点数(24))转换为浮点数(53)。你只是简单地使数字更精确。
float(24)的精度为7位,float(53)的精度为15位。
请参阅联机丛书> float和real(Transact-SQL):https://msdn.microsoft.com/en-GB/library/ms173773.aspx
如果我们重复你的例子并显示没有转换的变量,我们可以看到实数变量以7位精度显示,而浮点变量以14位数精度显示,这正是你设置的。
DECLARE @realVariable as real,
@floatVariable as float;
-- Set to a number with 14 digits precision
SET @realVariable=152304.11999512;
SET @floatVariable=152304.11999512;
SELECT @realVariable AS '@realVariable', @floatVariable AS '@floatVariable';
你的问题的简单答案是两个数字不一样。浮子(53)更精确。
计算两个数字之差的ABS,然后将其与可接受的阈值进行比较是一种方法。但是,如果规模可能差别很大,这将不会令人满意。
说明为什么这可能不令人满意:
r = 0.0001234567
f = 0.00012345678901234
将差异与阈值0.0005进行比较是没有用的。
因此,最好使用一个百分比的阈值。
DECLARE @threshold AS float, @delta AS float;
SET @threshold = ABS(@floatVariable / 1000000);
SET @delta = ABS(@floatVariable - CAST(@realVariable AS float));
SELECT @realVariable AS '@realVariable',
@floatVariable AS '@floatVariable',
@threshold AS '@threshold',
@delta AS '@delta',
CASE
WHEN @delta < @threshold THEN N'OK'
ELSE N'Different'
END AS 'Comparison';
注意:此解决方案可能需要对非常接近零的数字进行一些调整。
答案 1 :(得分:1)
@ RichardCL的描述描述了工作方式(+1)。现在,如果要将存储为real
数据类型值的值转换为存储为float
数据类型值的值,则整个精确的“原始”值将存储在结果值中 - 您将不会丢失现有real
值集中的信息。
参考您的示例,您的值152304.11999512无法精确存储为real
值 - 它将被舍入并存储为152304.125。将其转换为float
,您仍然会有152304.125。
答案 2 :(得分:0)
你需要一个三角洲。计算实数值和浮点值之间差值的绝对值,然后确保小于delta值。三角洲应足够小,以满足您的需求。
例如使用您的值: abs(152304.1250 - 152304.1200)&lt; = .0050所以使用.0050作为delta值。