我有连续字符串中存储的磅和便士的数据(遗憾的是没有办法解决这个问题),但不能保证2个小数位。
E.g。我的值可能为119.109
,因此必须将其翻译为带有截断的2位小数,即119.10
,而不是119.11
。
出于这个原因,我正在避免" CAST为Decimal"因为我不想圆。相反,我使用ROUND(amount, 2, 1)
强制截断2位小数。
这在很大程度上起作用,但有时表现出奇怪的行为。例如,119.10
输出为119.09
。这可以复制为:
ROUND(CAST('119.10' AS varchar),2,1)
我的目标字段是十进制(19,4)(但是第3和第4个小数位将始终为0,它是一个财务系统,所以总是磅和便士......)。
我认为这个问题与ROUNDing一个varchar有关......但是我不知道如何在没有CAST
的情况下知道这个问题,因此引入了这样的舍入方式?
这里发生了什么?
任何想法都非常感激。
答案 0 :(得分:3)
这是由于浮点数的工作方式,以及您的字符串编号在舍入之前被隐式转换为浮点数的事实。在您的测试用例中:
ROUND(CAST('119.10' AS varchar),2,1)
你隐式地将119.10
转换为float,以便它可以传递给ROUND
函数,119.10完全不能存储为浮点数,通过运行以下代码证明:
SELECT CAST(CONVERT(FLOAT, '119.10') AS DECIMAL(30, 20))
返回:
119.09999999999999000000
因此,当你使用truncate进行舍入时,得到119.09。
对于它的价值,你应该always specify a length when converting to, or declaring a varchar