Sql server 在不引入小错误的情况下,将SQL Server列从实型强制转换为浮点型

Sql server 在不引入小错误的情况下,将SQL Server列从实型强制转换为浮点型,sql-server,casting,floating-point,precision,Sql Server,Casting,Floating Point,Precision,我正在使用SQL Server数据库,在该数据库中,我需要将类型为real的列中的数据获取到另一个类型为float的表中的另一列中。根据我的理解,real基本上只是浮点,精度较低(24),而float默认精度为53。因此,当从real转换为float时,我希望实际获得更高的精度,或者至少不会丢失源值的精度。但是,在执行此操作时,某些精度实际上似乎丢失了: 为什么会发生这种情况?在执行此操作时,是否有方法至少保持源值的精度 我不明白为什么SSM在显示实际值时会舍入它们,而对浮点值却不舍入它们 最

我正在使用SQL Server数据库,在该数据库中,我需要将类型为
real
的列中的数据获取到另一个类型为
float
的表中的另一列中。根据我的理解,
real
基本上只是浮点,精度较低(24),而
float
默认精度为53。因此,当从real转换为float时,我希望实际获得更高的精度,或者至少不会丢失源值的精度。但是,在执行此操作时,某些精度实际上似乎丢失了:

为什么会发生这种情况?在执行此操作时,是否有方法至少保持源值的精度

我不明白为什么SSM在显示实际值时会舍入它们,而对浮点值却不舍入它们

最接近2.1的单精度浮点数(
real
)类似于2.099999。因此,将其显示为2.1是有意义的

最接近2.1的双精度浮点数(
float
)与 2.0999990000000,这大约是将2.0999999从
real
转换为
float
时得到的值

SSMS将显示更接近2.1的浮动为2.1,例如

select cast(2.1 as float), cast(2.1 as float) - 0.000000000000001 
显示为

---------------------- ----------------------
2.1                    2.1

这里有一篇文章回顾了这种转换的算法,并介绍了一种新的算法:

正如David Browne回答的补充:

看起来直接选角对你没有帮助。通过角色类型转换,可以获得“正确”(更好)的结果,如下一步:

select cast(cast(Valuef as nvarchar(20)) as float)

例如,
选择cast(cast(cast(2.1为real)作为nvarchar(20))作为float)
仅显示
2.1

真正的问题是,如果需要精确的值,为什么要使用
float
real
。您可以使用
ALTER
轻松更改列的数据类型;虽然如果列上有
约束
索引
es,您需要先
删除它们,然后重新创建它们。此外,如果有任何模式丰富的对象引用它们,则也需要删除并重新创建这些对象。您的源值不精确-SSMS只是以这种方式显示它们。“这些更改是否可以快速完成?”从技术上讲,您可以使用动态语句来更改它们,但它肯定不会考虑任何其他会阻碍操作的对象。您真正想要做的是在您的开发环境中创建迁移脚本,这样您就有了一个执行所有更改的大批量;至于德夫,你打破什么并不重要。至于在
ALTER
表时会发生什么,在DDL语句完成之前,查询可能会被阻塞。
float
仍然是一种不精确的数据类型。
real
float
都是。