XSL - 舍入/格式数问题

时间:2010-09-27 15:20:07

标签: xml xslt formatting numbers rounding

我正试图从我的xml中获取一个数字到2 dec的位置。

XML:<Quantity>0.0050</Quantity>

XSL:<xsl:value-of select="format-number($quantity, '####0.00')" />

然而,XSL似乎在此值上存在问题,并在页面的一个区域中输出0.00,在另一个区域中输出0.01。当然,在这种情况下,所有领域都有0.01输出是有利的。

另一个区域的值为4.221,但XSL正在输出4.23

我意识到format-number作为一种方法将数字转换为字符串。

不确定如何解决此问题。


修改

好的经过一段时间后,我发现这有效:

<xsl:value-of select='format-number( round(100*$quantity) div 100 ,"##0.00" )' />

通过此website

正如这个家伙所提到的那样,XSL使用“银行家四舍五入”来舍入到偶数而不是更大的数字。

解决方案似乎不太优雅,意味着为已经庞大而复杂的XSL文件添加大量额外功能。当然我错过了什么?

4 个答案:

答案 0 :(得分:20)

不确定为什么格式会如此不一致但是从内存来看它的规格是......复杂的。

同时,您可以使用round功能(ref)。这不是完美的,但功能性。如果您需要特定数量的sig figs,您可以使用 THE POWER OF MATHS!并执行以下操作:

<xsl:value-of select="round(yournum*100) div 100"/>

答案 1 :(得分:15)

我在XSLT / XPath 1.0中遇到了无穷无尽的小数问题,通常是将小数表示为浮点数并使用半偶数舍入(银行家舍入)的组合。不幸的是,由于浮点不精确,round(yournum*100) div 100方法对我不起作用。例如,将1.255乘以100得到125.49999999999999(这并不意味着依赖于实现,因为它应该是IEEE 754,但我不知道是否所有实现都遵循这一点)。四舍五入后,则得到125,而不是所需的126。

我采取了以下方法,我认为这种方法有效(尽管这总是一个棘手的领域,所以我不会声明太多的信心!)。但是,它取决于支持EXSLT扩展的XSLT引擎。它假设您想要舍入到小数点后两位。

<func:function name="local:RoundHalfUp">
    <xsl:param name="number"/>

    <xsl:choose>
        <xsl:when test="contains($number, '.')">
            <xsl:variable name="decimal" select="estr:split($number, '.')[2]"/>
            <xsl:choose>
                <xsl:when test="string-length($decimal) &gt; 2">
                    <func:result select="format-number(concat($number, '1'), '0.00')"/>
                </xsl:when>
                <xsl:otherwise>
                    <func:result select="format-number($number, '0.00')"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:when>
        <xsl:otherwise>
            <func:result select="format-number($number, '0.00')"/>
        </xsl:otherwise>
    </xsl:choose>

</func:function>

可以被称为:

<xsl:value-of select="local:RoundHalfUp(1.255)"/>

命名空间是:

xmlns:func="http://exslt.org/functions"
xmlns:estr="http://exslt.org/strings"
xmlns:local="http://www.acme.org/local_function"

重要的是要注意函数追加一个'1',而不是加0.001或类似。

如果它是一个选项(因为它有一个正确的十进制类型),最好使用XSLT 2.0,但我知道这通常不是一个选项(来自痛苦的经历!)。

答案 2 :(得分:0)

与上述所有答案相比,我找到了

<xsl:value-of select="format-number(xs:decimal($quantity), '####0.00')" />

很有用,它不会截断任何小数点值。截断确切的指定数字。如果数字是指数格式,我们可以使用如下:

<xsl:value-of select="format-number(xs:decimal(number($quantity)), '####0.00')" />

由于

答案 3 :(得分:0)

我还遇到了一个问题,如果您这样做     四舍五入($ number * 100)div 100 您会获得.4999999的浮点表示形式,并且舍入不能正常进行。

要解决此问题,这似乎可行:     回合($ number * 1000 div 10)div 100