将FLOAT(53)转换为VARCHAR(MAX)时为何出现舍入误差?
FLOAT(53)转VARCHAR(MAX)时的精度丢失问题解析
核心原因:SQL Server的CAST转换规则 + 浮点数存储特性
1. 浮点数的近似存储
FLOAT(53)属于双精度浮点数,以二进制格式存储十进制数值,很多小数(比如0.1、0.12)无法被精确表示,只能存储近似值。但你遇到的仅在整数部分为5位时丢失小数位的现象,主要由SQL Server的CAST函数行为决定,而非单纯的存储精度问题。
2. CAST(float → varchar)的默认格式化逻辑
SQL Server在将FLOAT转换为字符串时,默认遵循两个关键规则:
- 用最少的字符数唯一标识该浮点数;
- 最多显示15位有效数字(双精度浮点数的精度上限)。
针对你的示例场景:
- 当整数部分是4位(如
9980.12):整数部分占4位有效数字,剩余的有效数字位足够覆盖小数部分的两位,因此CAST会完整输出9980.12——这个字符串能唯一对应存储的近似值。 - 当整数部分是5位(如
10080.12):整数部分已经占了5位有效数字,此时存储的近似值(比如10080.119999999998)与10080.1的误差在浮点数的精度范围内,也就是说10080.1这个字符串已经能唯一标识该浮点数,无需额外保留第二位小数,因此CAST会自动截断为10080.1。
3. 微软推荐STR而非CAST的原因
微软官方文档说明:
当您要将float或real转换为字符数据时,使用STR字符串函数通常比CAST()更有用。这是因为STR能提供更多格式控制。有关详细信息,请参阅STR (Transact-SQL)和函数 (Transact-SQL)。
这是因为STR允许你显式指定总长度和小数位数,强制保留需要的精度,比如执行SELECT STR(@p, 7, 2)就能得到10080.12,不会出现自动截断的情况。
内容的提问来源于stack exchange,提问作者gordon613
相关产品推荐
相关产品推荐

