提问人:Narshe 提问时间:6/23/2020 最后编辑:Narshe 更新时间:6/24/2020 访问量:1144
从 varchar 转换为十进制而不会损失精度
Convert from varchar to decimal without precision loss
问:
我正在使用一个表,其中包含小数存储为 VARCHAR 的数值数据。这些数字的小数点数量不可预测(我相信最多 10 位),但它们也可以采用科学记数法('1231E-03')
我一直在尝试不同的解决方法来处理它们(就像这里解释的那样 https://stackoverflow.com/a/18452603/5866637)
我在转换常规十进制数时没有问题,但是在处理指数表示法时,我无法摆脱浮点精度问题。
DECLARE @Value VARCHAR(MAX) = '123456789.123e-5'
SELECT CONVERT(Decimal(38,18), CONVERT(float, @Value))
将解析为
1234.567891229999986535
是否可以进行任何转换,以便我可以将上面的数字转换为小数
1234.567891230000000000
我试过将一堆零连接到数字上,但是当我必须进行投射才能浮动时,它会吃掉所有这些额外的零。
我尝试的另一件事是降低十进制值的精度。如果我使用,我会得到预期的值,但这会导致问题吗?如果我知道我永远不会在数据库中获得超过小数点 13 位的值,那么使用 convert to (38,13) 是否安全,或者我应该寻求不同的解决方法?Decimal(38,13)
如果这被认为是重复的,我们将不胜感激,但我发现的最接近的匹配是上面的链接,它是 6 年前制定的。
答:
3赞
Igor
6/23/2020
#1
您可以使用 ROUND
DECLARE @Value VARCHAR(MAX) = '123456789.123e-5'
SELECT round(CONVERT(Decimal(38,18), CONVERT(float, @Value)), 8)
评论
1赞
John Cappelletti
6/23/2020
好答案。奇怪的是,当你四舍五入到 14+ +1 时,它就会破裂
0赞
Narshe
6/23/2020
是否可以传递动态计算的四舍五入金额?您的解决方案适用于具有 8 位有效数字的数字,但如果它有超过 8 个相关数字?J.F. 它四舍五入为'123456789.123456789e-3'
123456.789123460000000000
0赞
Igor
6/24/2020
你也许可以做一些数学运算来得到一个数字,并将其作为第二个参数传递给,但你为什么要在这一点上呢?我会根据您需要使用值的情况进行四舍五入或不四舍五入,而不是根据值本身做出决定。@Narsheround
0赞
Narshe
6/24/2020
我想避免四舍五入。我希望它可以像处理非 E 值一样工作,其中转换返回与文本上写的完全相同的数字。
评论
1234.567891230000000000
1234.56789123
SELECT CONVERT(Decimal(38,13), CONVERT(float, @Value))