我在 XSLT 中实现了以下阶乘函数:
<?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!
值?
最佳答案
除了 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"/>
产生正确的结果:
1241018070217667823424840524103103992616605577501693185388951803611996075221691752992751978120487585576464959501670387052 80988985869071076733124203221848436431047357788996854827829075454156196485215346831804429323959817369689965723590394761615227 8558180061176365108428800000000000000000000000000000000000000000
当然,我更愿意使用FXSL library来写这个在单个表达式中:
f:foldl(f:mult(), 1, 1 到 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>
关于xml - XSLT 限制中的阶乘?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1167570/