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

问题描述 投票:8回答:3

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

例如:

Float:               280712929.22 
Cast as Decimal:     280712929.2200000300
What I think I want: 280712929.2200000000

我对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

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

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

sql-server tsql floating-point decimal
3个回答
8
投票

你需要施放一次到圆形,然后再添加小数位(有其他方法,安全地,使用qazxsw poi,qazxsw poi等):

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; ,这是一种近似数据类型,并且在严格的数学背景之外为大多数人提供了逻辑。使用比您需要的更大比例的x d rd -------------- ---------------------- ---------------------- 280712929.22 280712929.2200000300 280712929.2200000000 364322379.5731 364322379.5730999700 364322379.5731000000 10482308902 10482308902.0000000000 10482308902.0000000000 ,并将其格式化为您现在需要的小数位数(在查询中,或创建视图,或创建计算列)。如果您存储的信息超出了现在的需求,您可以随时公开更多信息。您也可以选择不让用户直接访问您的表。


2
投票

我不确定这是否属于necroposting,但最近我遇到了类似的问题所以我想我可能会发布。

这可能是罪恶的丑陋,但似乎有效(从亚伦的回应中修改)。

FLOAT

结果:

DECIMAL

1
投票

当我需要将大数据表从float转换为decimal(28,15)时,我遇到了这个问题。正如在@Dan回答的评论中指出的那样,他的答案对于某些值没有按预期工作。

这是我用于进行更新的最终版本

DECLARE @myTable TABLE(x FLOAT);

INSERT INTO @myTable VALUES
   (280712929.22),
   (364322379.5731),
   (10482308902),   
   (-0.628475064730907);

SELECT x, 
       d = CONVERT(DECIMAL(28,10), x),                 
       NewDec = CONVERT(DECIMAL(28,10),           
                        CONVERT(DECIMAL(16,15), 
                                LEFT(CONVERT(VARCHAR(50), x, 2),17)) 
                        * POWER(CONVERT(DECIMAL(38,19),10),  
                                RIGHT(CONVERT(varchar(50), x,2),4)))                       
FROM @myTable; 

我放弃了一小部分精度因为我在小数点14上四舍五入。但在我的情况下这是可以接受的。

© www.soinside.com 2019 - 2024. All rights reserved.