如何在火鸟中加倍

时间:2017-02-09 13:03:39

标签: rounding firebird

表:

var1 | var2
-----+------
 0.5 | 19.99

var1和var2是双精度类型

我知道,保存的值可能是19.9900000000000000000000000001或19.989999999999999999999999999999999(或0.5不准确),但是如何获得正确的值(如果小数部分正好是0.5,正数向上舍入,负数向下舍入。 - 来自round definition):

SELECT var1, var2, round(var1*var2,2), round(0.5*19.99,2), round(9.995,2) FROM table

返回

var1 |  var2 | this should be 10 | this is 10         | this is also 10
     |       | round(var1*var2,2)| round(0.5*19.99,2) | round(9.995,2) 
-----+-------+-------------------+--------------------+-----------------
 0.5 | 19.99 |      9.99         |      10            |        10

我试过回合(圆(var1,2)*圆(var2,2))但没有改变

2 个答案:

答案 0 :(得分:2)

0.519.99等文字分别为NUMERIC(18, 1)NUMERIC(18, 2)。文字0.5 * 19.99NUMERIC(18, 3),这意味着结果值正好是9.995,当舍入到2位小时将导致NUMERIC(18, 3)值为10.000。

另一方面,对双精度值的相同操作并不精确。例如:

select 
    val1 * val2, 
    cast(val1 * val2 as varchar(100)), 
    round(val1 * val2, 2), 
    round(val1 * val2, 3), 
    round(round(val1 * val2, 3), 2), 
    round(val1 * val2 + 1e-10, 2)
from (
    select 
        cast(0.5 as double precision) as val1, 
        cast(19.99 as double precision) as val2 
    from rdb$database) a

将分别产生(在flamerobin中):

9.995000    9.994999999999999   9.990000    9.995000    10.000000   10.000000

第一列为9.995000是由flamerobin渲染的结果,最多6位小数(如第二列所示)。

这也可能暗示一个解决方案:首先轮到更高的小数位数,然后降低,或者添加一个小的分数,如1e-10,但这仍然会产生与其他值不正确的舍入。

将结果转换为定点小数也是如此:您可能会在某处引入舍入错误。

答案 1 :(得分:0)

现在的解决方案:

SELECT ROUND(CAST(var1 AS DECIMAL(9,2))*CAST(var2 AS DECIMAL(9,2)),2) FROM table

但也许有人有更好的解决方案