我们正面临着一个非常奇怪的问题,即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函数完全出现同样的问题。
答案 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>
</xsl:text>
<xsl:value-of select="round(100 * *)"/>
<xsl:text>
</xsl:text>
<xsl:value-of select="format-number(*, '#.00')"/>
<xsl:text>
</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中,您可以使用十进制数字,其行为更像人类所期望的那样。