将float转换为varchar

时间:2015-04-18 17:23:52

标签: sql-server floating-point rounding

我正在寻找一个函数F来将float x 转换为具有给定小数位精度的varchar, y

对于每个浮点数(x1,x2),F应具有以下属性:

Abs(x1 - x2) <= 10^(-y)表示F(x1,y) == F(x2,y)(其中==是字符串相等)。

我尝试过F = Str(Round(x,y),50)Cast(Round(x,y) as varchar)但是 x1 = -0.000001x2 = 0.000001我们有F(x1,5) = '-0'和F (x2, 5) = '0',未通过字符串相等测试。

使用小数作为intermadiary步骤将在处理大型浮动时打开异常(我认为)。

F的任何想法?

示例错误代码:

    declare @x1 float = -0.000001;
    declare @x2 float = 0.000001;
    declare @y int = 5;
    PRINT Str(Round(@x1,@y)) -- outputs -0
    PRINT Str(Round(@x2,@y)) -- output 0

[编辑19-04-2015]

我正在使用F=Str(Round(@x1+0.0,@y))进行测试 添加0.0是IEEE 754技巧,可以消除负零。

根据评论者请求添加预期结果:

F(-0.00001,4) = F(-0.00001,4) = "0"
F(-1,4) != F(1,4)  ("-1" != "1")
F(1.23456,4) = F(1.23457,4) ("1.2346" = "1.2346")
F(1.23454,4) != F(1.23455,4) ("1.2345" != "1.2346")

[编辑20-04-2015]

F = CAST(圆形(x + 0.0,y)为varchar)有效。结束问题。

2 个答案:

答案 0 :(得分:1)

问题是ROUND将返回一个float(基于输入类型)。 float不知道格式化和显示的小数精度。 使用STR定义要显示的长度和小数精度,而不先进行舍入。

DECLARE @x1 float = -0.000001; 
DECLARE @x2 float = 0.000001; 
DECLARE @y int = 5; -- decimal precision
DECLARE @z int = 30; -- total length of string
PRINT LTRIM(STR(@x1,@z,@y)); -- outputs -0.00000
PRINT LTRIM(STR(@x2,@z,@y)); -- output 0.00000

LTRIM将在开头删除填充空格。希望有所帮助。

要删除符号并获取标量值,请使用ABS功能。

DECLARE @x1 float = -0.000001; 
DECLARE @x2 float = 0.000001; 
DECLARE @y int = 5; -- decimal precision
DECLARE @z int = 30; -- total length of string
PRINT LTRIM(STR(ABS(@x1),@z,@y)); -- outputs 0.00000
PRINT LTRIM(STR(ABS(@x2),@z,@y)); -- output 0.00000

答案 1 :(得分:0)

F=CAST(Round(x + 0.0,y) as varchar)有效。