【问题标题】:Why rounding errors when casting float(53) to VARCHAR(MAX)为什么将 float(53) 转换为 VARCHAR(MAX) 时出现舍入错误
【发布时间】:2022-12-08 23:21:03
【问题描述】:
我知道浮点数不准确。 Why are floating point numbers inaccurate?。
我的问题是为什么简单转换为 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,但我仍然想了解为什么这正在发生。无论如何,微软的建议并没有说精度会丢失。
当您想将浮点数或实数转换为字符数据时,使用 STR 字符串
函数通常比 CAST( ) 更有用。这是因为 STR 使
对格式的更多控制。有关详细信息,请参阅 STR (Transact-SQL) 和
函数 (Transact-SQL)。
【问题讨论】:
标签:
tsql
floating-accuracy
【解决方案1】:
从 Microsoft doc 到 CAST 和 CONVERT :
句法
CAST ( expression AS data_type [ ( length ) ] )
CONVERT ( data_type [ ( length ) ] , expression [ , style ] )
...
浮动和真实样式
对于浮点数或实数表达式,样式可以具有下表中显示的值之一。其他值按 0 处理。
| Value |
Output |
| 0 (default) |
A maximum of 6 digits. Use in scientific notation, when appropriate. |
| 1 |
Always 8 digits. Always use in scientific notation. |
| 2 |
Always 16 digits. Always use in scientific notation. |
因此使用默认 0 样式,即最多 6 位数字。对于CAST,这似乎是不可避免的。
为避免舍入更多数字,可以改用 CONVERT 并传递非零样式,例如:
转换(VARCHAR(最大),@q,1)