我在XSLT中实现了以下factorial函数:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:apply-templates>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="factorial" name="factorial">
<xsl:param name="n" select="@n" />
<xsl:param name="f" select="1" />
<xsl:if test="$n > 1">
<xsl:call-template name="factorial">
<xsl:with-param name="n">
<xsl:value-of select="$n - 1" />
</xsl:with-param>
<xsl:with-param name="f">
<xsl:value-of select="$f * $n" />
</xsl:with-param>
</xsl:call-template>
</xsl:if>
<xsl:if test="$n = 1">
<xsl:value-of select="$f" />
</xsl:if>
</xsl:template>
</xsl:stylesheet>
在Firefox和IE7中,170!
工作正常但171!
仅返回NaN
。这是XSLT / XPath数学中明确定义的限制,还是有一种方法可以获得更高的n!
值?
答案 0 :(得分:3)
为XPath 1.0添加正确答案,在XPath 2.0中有xs:integer数据类型, xs:integer 的绝对值没有最大值。
Saxon实现了BigInteger算法,并给出了代码(通过添加xs:integer类型略有改变):
<xsl:template match="factorial" name="factorial">
<xsl:param name="n" as="xs:integer"
select="xs:integer(@n)" />
<xsl:param name="f" as="xs:integer" select="1" />
<xsl:if test="$n gt 1">
<xsl:call-template name="factorial">
<xsl:with-param name="n">
<xsl:value-of select="$n - 1" />
</xsl:with-param>
<xsl:with-param name="f">
<xsl:value-of select="$f * $n" />
</xsl:with-param>
</xsl:call-template>
</xsl:if>
<xsl:if test="$n = 1">
<xsl:value-of select="$f" />
</xsl:if>
</xsl:template>
当它应用于以下XML文档时:
<factorial n = "171"/>
产生了正确的结果:
1241018070217667823424840524103103992616605577501693185388951803611996075221691752992751978120487585576464959501670387052809889858690710767331242032218484364310473577889968548278290754541561964852153468318044293239598173696899657235903947616152278558180061176365108428800000000000000000000000000000000000000000
当然,我更喜欢在单个表达式中使用FXSL library来写这个:
<强> f:foldl(f:mult(), 1, 1 to 171)
强>
在这个XSLT样式表中:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f="http://fxsl.sf.net/"
>
<xsl:import href="../f/func-dvc-foldl.xsl"/>
<xsl:import href="../f/func-Operators.xsl"/>
<xsl:output encoding="UTF-8" method="text"/>
<xsl:template match="/">
<xsl:value-of select="f:foldl(f:mult(), 1, 1 to 171)"/>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:2)
答案 2 :(得分:0)
我猜测你的问题是依赖于XSLT实现的。
这看起来像标准的溢出问题。我通过使用此处的JavaScript因子实现复制问题找到了一个提示:http://www.cs.uml.edu/~ytran/factorial.html
在另一种语言中,我会使用BigInteger库来获得如此大的数字。使用Google快速搜索[terms:XSLT BigInteger]会发现XSLT没有原生的BigInteger类型。