我们在使用XSLT舍入和格式化数字函数时遇到了一个非常奇怪的问题。假设我有一个像131.855这样的数字,我想把它四舍五入到小数点后两位。我期望131.86作为答案,但是XSLT round()函数将其舍入为131.85。我尝试使用“round(131.855*100)div100”,但它不起作用。然而,如果我必须舍入一个像127.855这样的数字,它确实会使用相同的代码正确地舍入为127.86,即" round (127.855 *100)div100“。此外,奇怪的是,如果我尝试四舍五入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.round函数上。
发布于 2015-10-23 05:40:40
您可以使用以下内容:
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
发布于 2015-10-23 08:23:08
首先要理解的是,当你写一个像131.855这样的数字时,它表示的实际值并不完全是131.85和131.86之间的一半。不存在数值上完全等于131.855的双精度浮点数,因此您正在操作的实际值略低于或略高于该值。当你写下数字的时候,这种不精确就会出现,它不仅仅是当你在上面做算术的时候出现的。当你将它乘以100时,这个差值会被放大,当你使用round()时,它会得到最近的整数,这将取决于最初的近似值是向上还是向下。因此,由于XSLT 1.0只提供浮点数,因此没有办法避免这种问题。
在XSLT 2.0中,您可以使用十进制数字,它的行为更符合人类的期望。
https://stackoverflow.com/questions/33295141
复制相似问题