在XSLT樣式表中使用萊布尼茲級數計算π的近似值

初學XSLT的時候一直糾結它對循環的處理,一開始使用for-each進行簡單的遍歷操做,可是對更精確的循環控制總感受力不從心。後來我在《XSLT從入門到精通》這本書中看到了一個概念「Side-Effect-Free」-基本意思就是用戶不能更新變量值,所以用戶對於控制函數環境只有很是有限的能力-才知道XSLT中的variable的值是沒法進行二次修改的。所以,相似高級語言(如C++)中如「for(int i = 0; i < n; i++) { }」裏的變量i,就不能實現了。後來我又研究了下,XSLT的循環是經過對模板(template)的遞歸實現的。下面是一段我寫的計算圓周率的XSLT代碼,使用萊布尼茨級數(Leibniz series)遞歸求出π/4的近似值,而後輸出它的4倍即π的近似值。html

1.XML文件「loop.xml」的代碼ide

下面代碼中COUNT指定遞歸次數,即「loop.xslt」中模板CALCULATE的調用次數函數

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type='text/xsl' href='loop.xslt'?>
<LOOP COUNT="10000" />

2.XSLT文件「loop.xslt」的代碼oop

計算依據:π的萊布尼茨公式(π/4=1-1/3+1/5-1/7+1/9-...)ui

<?xml version="1.0" encoding="gb2312"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="html" />
  
  <!--遞歸計算Pi值-->
  <xsl:template name="CALCULATE">
    <xsl:param name="LOOP"/>
    <xsl:param name="COUNT"/>
    <xsl:param name="SIGN"/>
    <xsl:param name="VALUE"/>
    
    <xsl:if test="number($LOOP) &lt; number($COUNT) + 1">
      <xsl:value-of select ="number($VALUE) * 4"/>
      <xsl:text>, </xsl:text>
      <xsl:call-template name="CALCULATE">
        <xsl:with-param name="LOOP" select="number($LOOP) + 1"/>
        <xsl:with-param name="COUNT" select="number($COUNT)"/>
        <xsl:with-param name="SIGN" select="number($SIGN) * (-1)"/>
        <xsl:with-param name="VALUE" select="number($VALUE) + number($SIGN) div (number($LOOP) * 2 + 1)"/>
      </xsl:call-template>
    </xsl:if>
  
  </xsl:template>
    
  <!--計算Pi值-->
  <xsl:template match="/">
    
    <xsl:variable name="INIT_LOOP" select="1"/>
    <xsl:variable name="INIT_COUNT" select="/LOOP/@COUNT"/>
    <xsl:variable name="INIT_SIGN" select="-1"/>
    <xsl:variable name="INIT_VALUE" select="1"/>
      
    <html>
        <head>        
            <meta content="zh-cn" http-equiv="Content-Language"/>
        <meta content="text/html; charset=utf-16" http-equiv="Content-Type"/>
          <title> &#960;的萊布尼茨公式</title>
        </head>
        <body>
        
        <xsl:text>計算&#960;值 遞歸次數:</xsl:text>
        <xsl:value-of select="$INIT_COUNT"/>
        
        <hr/>
        
        <xsl:variable name="RESULT" >
          <xsl:call-template name="CALCULATE">
            <xsl:with-param name="LOOP" select="$INIT_LOOP"/>
            <xsl:with-param name="COUNT" select="$INIT_COUNT"/>
            <xsl:with-param name="SIGN" select="$INIT_SIGN"/>
            <xsl:with-param name="VALUE" select="$INIT_VALUE"/>
          </xsl:call-template>
        </xsl:variable>
        <xsl:value-of select="$RESULT"/>
        <xsl:text>...</xsl:text>
      
        </body>
      </html>
  
  </xsl:template>

</xsl:stylesheet>

3.loop.xml打開後的效果.net

這個程序迭代10000次後,得出的結果爲:3.1414926535900345code

附:幾個維基百科上的條目orm

1)函數的反作用:https://en.wikipedia.org/wiki/Side_effect_%28computer_science%29xml

2)π的萊布尼茨公式:https://en.wikipedia.org/wiki/Leibniz_formula_for_%CF%80htm

---------------------------------------------------------------------------------------------------------

後來我又發現了一個更簡單高效的方法讓XSLT去計算Pi值,即經過在XSLT中嵌入VBScript來完成計算邏輯,詳見這篇文章:《在XSLT樣式表中插入VBScript腳本進行數學計算

END

相關文章
相關標籤/搜索