xml - XSLT 限制中的阶乘?

标签 xml internet-explorer firefox xslt

我在 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 &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>
</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/

相关文章:

javascript - Excel/CSV 与站点的连接

java - Readline 太慢了——还有更快的吗?

javascript - onChange 事件永远不会在 Internet Explorer 中为 <select> 触发

html - 使用位置 :relative and top/margin-top? 的 Firefox 4 呈现差异

css - firefox 在伪元素周围添加了奇怪的空间

google-chrome - Firefox 或 Chrome 的 SOAP 客户端扩展

c# - 如何在 C# 中从 XML 中读取键值

python - 如何从 Google App Engine 应用程序解析 XML?

javascript - fullcalendar 在 IE 中不渲染事件(所有版本)

javascript - window.onfocus 在 IE7 中不触发,在 Opera 中不一致