XSLT舍入问题



我们在使用XSLT舍入和Format-number函数时遇到了一个非常奇怪的问题。假设有一个数字,比如131.855,我想把它四舍五入到小数点后两位。我希望答案是131.86,但XSLT round()函数将其舍入为131.85。我尝试使用"圆形(131.855*100)div 100",但它不起作用。然而,如果我要把一个数字四舍五入,比如127.855,它会用同样的代码正确地四舍五入到127.86。"round(127.855 *100)div 100"。此外,奇怪的是,如果我尝试将131.755四舍五入,它确实四舍五入到131.76!!很奇怪。我们也尝试使用format-number()函数,但也会得到奇怪的结果。例如,如果我取数字349615.225,并在此使用format-number,即format-number(349615.225,'#.##'),它会给出349615.22,而我期望小数是。23。但是如果我在131.855上使用format-number,它会被转换为131.86…

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

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

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

编辑:

奇怪的是,同样的问题也发生在Java的Math中。圆的函数。

您可以使用以下命令:

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

首先要理解的是,当您写一个像131.855这样的数字时,它所代表的实际值并不完全是131.85和131.86之间的中间值。没有双精度浮点数在数值上完全等于131.855,因此您正在操作的实际值略低于或略高于此值。当你把数字写下来的时候,这种不精确性就会出现,而不仅仅是当你对它做算术的时候。当你把它乘以100时,这个差会被放大,当你使用round()时,它会变成最接近的整数,这取决于最初的近似值是上还是下。因此,鉴于XSLT 1.0只提供浮点数,没有办法避免这种问题。

在XSLT 2.0中可以使用十进制数,它的行为更符合人们的期望。

相关内容

  • 没有找到相关文章

最新更新