我正在寻找一个函数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.000001
和x2 = 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)有效。结束问题。
答案 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)
有效。