XSLT舍入问题

时间:2015-10-23 04:57:20

标签: xml xslt xslt-1.0 rounding

我们正面临着一个非常奇怪的问题,即XSLT舍入和格式数函数。假设我有一个像131.855这样的数字,我想把它四舍五入到小数点后两位。我希望131.86作为答案,但XSLT round()函数将其舍入到131.85。我尝试使用" round(131.855 * 100)div 100"但它不起作用。然而,如果我必须舍入像127.855这样的数字,它会使用相同的代码正确地舍入到127.86,即" round(127.855 * 100)div 100"。另外,奇怪的是,如果我试图完成131.755,它确实会被舍入到131.76!很奇怪。 我们也尝试使用format-number()函数,但这也给出了奇怪的结果。例如,如果我使用数字349615.225并且我使用格式编号,即格式编号(349615.225,'#。##'),它给出349615.22,而我希望小数为.23。但是,如果我在131.855上使用format-number,它会转换为131.86 ......

我也尝试在format-number()中使用round()函数,但它也给出了类似的结果..

我们正在使用XSLT 1.0。更改为XSLT 2.0似乎是一项艰巨的任务。我看到的唯一解决方法是使用一些java函数并在XSL中调用它来进行四舍五入。

任何想法都将受到高度赞赏。

编辑:

奇怪的是,Java的Math.round函数完全出现同样的问题。

2 个答案:

答案 0 :(得分:1)

您可以使用以下内容:

format-number(round(100 * $number) div 100, '#.00')

round()函数将数字四舍五入为最接近的整数,只使用round()可能无法正确舍入数字。
format-number()通过修剪数据来格式化数字(我猜),这可能导致价值损失 使用round()format-number()都可以有效地发挥作用。

下面的例子描述了不同的行为。

输入:

<root>5.225</root>

XSLT:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="text" />
    <xsl:template match="/">
        <xsl:value-of select="round(*)"/>
        <xsl:text>&#xa;</xsl:text>
        <xsl:value-of select="round(100 * *)"/>
        <xsl:text>&#xa;</xsl:text>
        <xsl:value-of select="format-number(*, '#.00')"/>
        <xsl:text>&#xa;</xsl:text>
        <xsl:value-of select="format-number(round(100 * *) div 100, '#.00')"/>
    </xsl:template>
</xsl:transform>

输出:
5
523个
5.22
5.23

答案 1 :(得分:0)

首先要理解的是,当你写一个像131.855这样的数字时,它所代表的实际值并不完全在131.85和131.86之间。没有双精度浮点数在数值上完全等于131.855,因此您操作的实际值略低于或略高于该值。一旦你将数字写下来就会产生这种不精确的现象,它不仅会在你对其进行算术时产生。当你将它乘以100时,这个差异会被放大,当你使用round()时,它会转到最接近的整数,这取决于近似值是先上升还是下降。因此,鉴于XSLT 1.0仅提供浮点数,因此无法避免此类问题。

在XSLT 2.0中,您可以使用十进制数字,其行为更像人类所期望的那样。