为什么在将 float(53) 转换为 VARCHAR(MAX) 时出现舍入错误

Why rounding errors when casting float(53) to VARCHAR(MAX)

提问人:gordon613 提问时间:12/8/2022 最后编辑:Thom Agordon613 更新时间:12/9/2022 访问量:59

问:

我知道浮点数不准确。为什么浮点数不准确?

我的问题是,为什么简单的强制转换为 a 有时会失去精度,以及为什么这似乎只发生在点前有五位数字时。varchar(max)

例如,当浮点数在点之前有四位以上的数字时。小数点后的第二位数字有时会丢失。例如。

declare @p FLOAT(53)
set @p=10080.12
select @p,cast(@p as VARCHAR(max))

10080.12 10080.1

在这里,浮点数在点之前有四位数字,它可以工作。

declare @q float(53)
set @q=9980.12
select @q,cast(@q as VARCHAR(max))

9980.12 9980.12

我注意到 Microsoft 建议使用 STR 而不是 CAST,但我仍然想了解为什么会发生这种情况。无论如何,Microsoft的建议并没有说会失去精度。

当您想将浮点数或实数转换为字符数据时,请使用 STR 字符串 函数通常比 CAST( ) 更有用。这是因为 STR 使 更好地控制格式。有关详细信息,请参阅 STR (Transact-SQL) 和 函数 (Transact-SQL)。

T-SQL 浮动精度

评论


答:

3赞 Renat 12/8/2022 #1

来自 Microsoft 文档和 :CASTCONVERT

语法

CAST ( expression AS data_type [ ( length ) ] )

CONVERT ( data_type [ ( length ) ] , expression [ , style ] )

...

浮动和真实样式

对于浮点数或实数表达式,style 可以具有下表中所示的值之一。其他值处理为 0。
价值 输出
0 (默认) 最多 6 位数字。在适当的情况下,在科学记数法中使用。
1 始终为 8 位数字。始终以科学记数法使用。
2 始终为 16 位数字。始终以科学记数法使用。

因此,使用默认的 0 样式,最多 6 位数字。这似乎是不可避免的。CAST

要使用更多数字,可以使用问题中提到的函数。或者使用非零样式参数(这将使用科学记数法),例如:STRCONVERT

转换(VARCHAR(最大值), @q, 1)

评论

1赞 gordon613 12/9/2022
非常感谢!但是,我注意到,将 CONVERT 与非零样式一起使用将始终导致科学记数法,这可能并不总是可取的。
0赞 Renat 12/9/2022
感谢您强调这一点,更新的答案提到了它