我将英镑和便士的数据存储在连接的字符串中(不幸的是没有办法解决这个问题),但不能保证2位小数。
。我可能会得到一个119.109
的值,所以它必须转换为2位小数,即119.10
,而不是119.11
。
出于这个原因,我避免了"CAST as Decimal",因为我不想舍入。相反,我使用ROUND(amount, 2, 1)
强制截断小数点后2位。
这在大多数情况下是有效的,但有时会表现出奇怪的行为。例如,119.10
输出为119.09
。这可以复制为:
ROUND(CAST('119.10' AS varchar),2,1)
我的目标字段是Decimal(19,4)(但是小数点后第3位和第4位总是0,这是一个金融系统,所以总是英镑和便士…)。
我认为问题与varchar的舍入....有关但是如果没有CAST
,我就不知道怎么做了,所以我引入了四舍五入?
这是怎么回事?
这是由于浮点数的工作方式,以及您的字符串数在四舍五入之前隐式转换为浮点数的事实。在您的测试用例中:
ROUND(CAST('119.10' AS varchar),2,1)
您隐式地将119.10
转换为浮点数,以便它可以传递给ROUND
函数,119.10确切地不能存储为浮点数,通过运行以下代码证明:
SELECT CAST(CONVERT(FLOAT, '119.10') AS DECIMAL(30, 20))
返回:
119.09999999999999000000
因此,用truncate四舍五入得到119.09。
无论如何,在转换为或声明varchar