将Float转换为十进制(SQL Server)

C W*_*ker 8 t-sql sql-server floating-point decimal

我需要在SQL Server中将Float转换为Decimal(28,10).我的问题是,由于浮动的性质和转换的方式,简单地转换浮动可能会使我的用户看起来错误的数字.

例如:

Float:               280712929.22 
Cast as Decimal:     280712929.2200000300
What I think I want: 280712929.2200000000
Run Code Online (Sandbox Code Playgroud)

我对float的工作方式有点了解(这是一种近似的数据类型等),但不足以理解为什么它最后添加了300.它只是垃圾作为转换的副作用,还是以某种方式更精确地表示浮动实际存储的内容?对我来说,它似乎是凭空而来的精确度.

最终,我需要它是准确的,但也要看起来"正确".我想我需要得到那个底部数字,因为它看起来我刚刚添加了尾随零.这可能吗?这是一个好主意还是坏主意,为什么?其他建议是受欢迎的.

其他一些例子:

Float:           364322379.5731
Cast as Decimal: 364322379.5730999700
What I want:     364322379.5731000000

Float:           10482308902
Cast as Decimal: 10482308901.9999640000
What I want:     10482308902.0000000000
Run Code Online (Sandbox Code Playgroud)

附注:我将这些值放入的新数据库表是我的用户可读的.它们实际上现在只需要两个小数位,但是将来可能会改变,所以我们决定使用Decimal(28,10).长期目标是将我获取数据的浮点数转换为小数.

编辑:有时我的浮点数比我需要的小数位数多,例如:-0.628475064730907.在这种情况下,施法到-0.6284750647就好了.我基本上需要我的结果将零添加到浮点的末尾,直到我有10个小数位.

Aar*_*and 8

你需要一次转换为圆形,而一旦加小数回(还有其他的方法也一样,当然,使用STR,ROUND等):

DECLARE @c TABLE(x FLOAT);

INSERT @c SELECT 280712929.22;
INSERT @c SELECT 364322379.5731;
INSERT @c SELECT 10482308902;

SELECT x, 
    d = CONVERT(DECIMAL(28,10), x), 
    rd = CONVERT(DECIMAL(28,10), CONVERT(DECIMAL(28,4), x))
FROM @c;
Run Code Online (Sandbox Code Playgroud)

结果:

x               d                       rd
--------------  ----------------------  ----------------------
280712929.22    280712929.2200000300    280712929.2200000000
364322379.5731  364322379.5730999700    364322379.5731000000
10482308902     10482308902.0000000000  10482308902.0000000000
Run Code Online (Sandbox Code Playgroud)

如果您希望它准确并且看起来正确,请停止使用FLOAT,这是一种近似数据类型,并且在严格的数学背景之外的大多数人都无法使用逻辑.使用DECIMAL比您需要的更大的比例,并将其格式化为您现在需要的小数位数(在查询中,或创建视图,或创建计算列).如果您存储的信息超出了现在的需求,您可以随时公开更多信息.您也可以选择不让用户直接访问您的表.

  • 如果您需要有条件地决定每行显示多少小数位,根据该行中的值,我认为您正在跨越字符串解析/格式化区域.这可能最好在表示层完成,而不是在数据库中完成. (2认同)
  • 然后我仍然建议使用客户端语言而不是查询更好地完成格式化.SQL的优势不在于字符串解析,这就是它的含义. (2认同)