为什么在SQL Server中将float转换为varchar时会进行四舍五入?

13

以下SQL语句,

declare @a as float, @b as float

select @a=1.353954 , @b=1.353956
select 
CAST(@a as VARCHAR(40)) AS a_float_to_varchar ,
CAST(@b as VARCHAR(40)) AS b_float_to_varchar

导致

a_float_to_varchar                       b_float_to_varchar
---------------------------------------- ----------------------------------------
1.35395                                  1.35396

基于 'float' 和 'real' (Transact-SQL)

Float 的精度为 15 位数字,所以我不确定为什么在转换为 varchar 时该数字被四舍五入了。


关于“浮点数的精度为15位数字”的说法:这并不是一个确切的数字(可能存在几个双关语)。实际上,这个数字更像是15到16 - 或许取决于实际数字(?)。从“双精度浮点格式”中了解到:“53位有效数字的精度可提供15至17个有效十进制数字的精度”。 - Peter Mortensen
3个回答

18

从您的链接中可以看到(实际上是第一行):

近似数字数据类型...

如果您需要精确的精度,请不要使用float

话虽如此,有一个函数STR()专门用于将float转换为字符数据类型。


我知道float是近似类型,但是“15位数字精度”的确切含义是什么?虽然建议不要使用float,但有些情况下我们无法排除float的使用,例如遗留应用程序。 - N30
@N30 - 如果您的内容超过15位数字,它将无法被存储。尽管可能会尝试重新计算,但结果并不准确。 - JNK
2
@JNK,这正是我所问的。如果值小于15位数字,例如1.353954,则将其转换为varchar(40)应该像1.353954,然后是0直到第15位数字,然后是近似序列,但在6个字符后四舍五入。我将尝试使用STR()并告诉您结果。 - N30
@JNK 我想在第二次阅读您的评论后,我明白了...它被存储为15位数字,但仍然是近似存储的。 - N30
str() 只是具有不同的默认设置,可以进行修改以显示更多或更少的精度。STR(float_expression[, length[, decimal]]) https://msdn.microsoft.com/zh-cn/library/ms189527.aspx - blindguy

6

在转换为varchar之前先将其转换为decimal

declare @a as float, @b as float

select @a=1.353954 , @b=1.353956
select
CAST(CAST(@a AS DECIMAL(38,18)) as VARCHAR(40)) AS a_float_to_varchar ,
CAST(CAST(@b AS DECIMAL(38,18)) as VARCHAR(40)) AS b_float_to_varchar

6

你可以指定样式来包含更多数字。

declare @gg float
set @gg = 124.323125453
SELECT @gg,Convert(varchar, @gg,128)

对于更新版本的SQL Server,请使用SELECT @gg,Convert(varchar, @gg,3)

返回结果为

124.323125453    124.323125453

参考:CAST 和 CONVERT (Transact-SQL)

或者使用 STR() 函数:

declare @gg float
set @gg = 124.323124354234524
SELECT @gg,str(@gg,16,15)

它应该给出所有可能的数字。总长度为16(包括小数点),最多可以有15位小数(实际上,0.2323...中的0计入长度,因此如果所有数字都小于1,则长度需要为17)。但是,STR()会在结果前面填充空格并在后面添加零。


Convert方法非常棒,是个很好的答案。在StackExchange和许多其他网站上,大多数对这个问题的回答都围绕着将其转换为十进制数,但如果您事先不知道精度和比例,则无法选择此选项。 - SQLServerSteve

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接