home *** CD-ROM | disk | FTP | other *** search
/ Programmer Plus 2007 / Programmer-Plus-2007.iso / Programming / XML Utilities / Professional Programmer XSL IDE / Xselerator25.msi / Data.Cab / F44506_numberutils_lib.xsl < prev    next >
Encoding:
Extensible Markup Language  |  2002-03-07  |  18.7 KB  |  396 lines

  1. <?xml version="1.0"?>
  2. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  3. <!--
  4. ==========================================================================
  5.  Stylesheet: numberutils_lib.xsl
  6.     Version: 1.0 (2002-01-21)
  7.      Author: Martin "Marrow" Rowlinson
  8.      Notice: (c)2001,2002 MarrowSoft Limited.  ALL RIGHTS RESERVED.
  9.              No limitation on use - except this code may not be published,
  10.              in whole or in part, without prior written consent of copyright
  11.              owner.
  12. ========================================================================== -->
  13.  
  14. <!-- ========================================================= -->
  15. <!-- Function: Bin2Dec(<value>) => Decimal value               -->
  16. <!-- Parameters:-                                              -->
  17. <!--   <value>  - the binary string to be converted to decimal -->
  18. <xsl:template name="Bin2Dec">
  19.     <xsl:param name="value" select="'0'"/>
  20.     <!-- the following paremeters are used only during recursion -->
  21.     <xsl:param name="bin-power" select="number(1)"/>
  22.     <xsl:param name="accum" select="number(0)"/>
  23.     <!-- isolate last binary digit  -->
  24.     <xsl:variable name="bin-digit" select="substring($value,string-length($value),1)"/>
  25.     <!-- check that binary digit is valid -->
  26.     <xsl:choose>
  27.         <xsl:when test="not(contains('01',$bin-digit))">
  28.             <!-- not a binary digit! -->
  29.             <xsl:text>NaN</xsl:text>
  30.         </xsl:when>
  31.         <xsl:when test="string-length($bin-digit) = 0">
  32.             <!-- unexpected end of hex string -->
  33.             <xsl:text>0</xsl:text>
  34.         </xsl:when>
  35.         <xsl:otherwise>
  36.             <!-- OK so far -->
  37.             <xsl:variable name="remainder" select="substring($value,1,string-length($value)-1)"/>
  38.             <xsl:variable name="this-digit-value" select="number($bin-digit) * $bin-power"/>
  39.             <!-- determine whether this is the end of the hex string -->
  40.             <xsl:choose>
  41.                 <xsl:when test="string-length($remainder) = 0">
  42.                     <!-- end - output final result -->
  43.                     <xsl:value-of select="$accum + $this-digit-value"/>
  44.                 </xsl:when>
  45.                 <xsl:otherwise>
  46.                     <!-- recurse to self for next digit -->
  47.                     <xsl:call-template name="Bin2Dec">
  48.                         <xsl:with-param name="value" select="$remainder"/>
  49.                         <xsl:with-param name="bin-power" select="$bin-power * 2"/>
  50.                         <xsl:with-param name="accum" select="$accum + $this-digit-value"/>
  51.                     </xsl:call-template>
  52.                 </xsl:otherwise>
  53.             </xsl:choose>
  54.         </xsl:otherwise>
  55.     </xsl:choose>
  56. </xsl:template>
  57.  
  58. <!-- ======================================================== -->
  59. <!-- Function: Hex2Dec(<value>) => Decimal value              -->
  60. <!-- Parameters:-                                             -->
  61. <!--   <value>  - the hex string to be converted to decimal   -->
  62. <!--              (case of hex string is unimportant)         -->
  63. <xsl:template name="Hex2Dec">
  64.     <xsl:param name="value" select="'0'"/>
  65.     <!-- the following paremeters are used only during recursion -->
  66.     <xsl:param name="hex-power" select="number(1)"/>
  67.     <xsl:param name="accum" select="number(0)"/>
  68.     <!-- isolate last hex digit (and convert it to upper case) -->
  69.     <xsl:variable name="hex-digit" select="translate(substring($value,string-length($value),1),'abcdef','ABCDEF')"/>
  70.     <!-- check that hex digit is valid -->
  71.     <xsl:choose>
  72.         <xsl:when test="not(contains('0123456789ABCDEF',$hex-digit))">
  73.             <!-- not a hex digit! -->
  74.             <xsl:text>NaN</xsl:text>
  75.         </xsl:when>
  76.         <xsl:when test="string-length($hex-digit) = 0">
  77.             <!-- unexpected end of hex string -->
  78.             <xsl:text>0</xsl:text>
  79.         </xsl:when>
  80.         <xsl:otherwise>
  81.             <!-- OK so far -->
  82.             <xsl:variable name="remainder" select="substring($value,1,string-length($value)-1)"/>
  83.             <xsl:variable name="this-digit-value" select="string-length(substring-before('0123456789ABCDEF',$hex-digit)) * $hex-power"/>
  84.             <!-- determine whether this is the end of the hex string -->
  85.             <xsl:choose>
  86.                 <xsl:when test="string-length($remainder) = 0">
  87.                     <!-- end - output final result -->
  88.                     <xsl:value-of select="$accum + $this-digit-value"/>
  89.                 </xsl:when>
  90.                 <xsl:otherwise>
  91.                     <!-- recurse to self for next digit -->
  92.                     <xsl:call-template name="Hex2Dec">
  93.                         <xsl:with-param name="value" select="$remainder"/>
  94.                         <xsl:with-param name="hex-power" select="$hex-power * 16"/>
  95.                         <xsl:with-param name="accum" select="$accum + $this-digit-value"/>
  96.                     </xsl:call-template>
  97.                 </xsl:otherwise>
  98.             </xsl:choose>
  99.         </xsl:otherwise>
  100.     </xsl:choose>
  101. </xsl:template>
  102.  
  103. <!-- ===================================================== -->
  104. <!-- Function: Dec2Hex(<value>[,<digits>]) => Hex string   -->
  105. <!-- Parameters:-                                          -->
  106. <!--   <value>  - the decimal value to be converted to hex -->
  107. <!--              (must be a positive)                     -->
  108. <!--   <digits> - the number of hex digits required        -->
  109. <!--              If this parameter is omitted then the    -->
  110. <!--              hex string returned is as long as reqd.  -->
  111. <!--              If the number of digits required exceeds -->
  112. <!--              the value specified by this parameter    -->
  113. <!--              then the hex string is as long as reqd.  --> 
  114. <xsl:template name="Dec2Hex">
  115.     <xsl:param name="value" select="number(0)"/>
  116.     <xsl:param name="digits" select="number(-1)"/>
  117.     <!-- the following paremeters are used only during recursion -->
  118.     <xsl:param name="hex" select="number(268435456)"/>
  119.     <xsl:param name="hex-power" select="number(28)"/>
  120.     <xsl:param name="nonzero-encounters" select="false()"/>
  121.     <!-- calculate the left over value to be passed to next recursion -->
  122.     <xsl:variable name="remainder" select="floor($value) mod $hex"/>
  123.     <!-- calculate the value of this nybble (this hex digit) -->
  124.     <xsl:variable name="this-nybble" select="(floor($value) - $remainder) div ($hex)"/>
  125.     <!-- determine whether a non-zero digit has been encountered yet -->
  126.     <xsl:variable name="nonzero-encountered" select="boolean($nonzero-encounters or ($this-nybble > 0))"/>
  127.     <!-- only output hex digit if:-                   -->
  128.     <!--     non-zero has already been encountered OR -->
  129.     <!--     on the last digit OR                     -->
  130.     <!--     the number of required digits says so    -->
  131.     <xsl:if test="$nonzero-encountered or ($hex-power = 0) or ((($hex-power div 4) + 1) <= $digits)">
  132.         <xsl:value-of select="substring('0123456789ABCDEF',($this-nybble)+1,1)"/>
  133.     </xsl:if>
  134.     <!-- recursive call until all digits have been dealt with -->
  135.     <xsl:if test="$hex-power > 0">
  136.         <xsl:call-template name="Dec2Hex">
  137.             <xsl:with-param name="value" select="$remainder"/>
  138.             <xsl:with-param name="hex" select="$hex div 16"/>
  139.             <xsl:with-param name="hex-power" select="$hex-power - 4"/>
  140.             <xsl:with-param name="digits" select="$digits"/>
  141.             <xsl:with-param name="nonzero-encounters" select="$nonzero-encountered"/>
  142.         </xsl:call-template>
  143.     </xsl:if>
  144. </xsl:template>
  145.  
  146. <!-- ======================================================== -->
  147. <!-- Function: Dec2Bin(<value>) => Binary string              -->
  148. <!-- Parameters:-                                             -->
  149. <!--   <value>  - the decimal value to be converted to binary -->
  150. <!--              (must be a positive)                        -->
  151. <xsl:template name="Dec2Bin">
  152.     <xsl:param name="value" select="number(0)"/>
  153.     <!-- the following paremeters are used only during recursion -->
  154.     <xsl:param name="bin" select="number(2147483648)"/>
  155.     <xsl:param name="bin-power" select="number(31)"/>
  156.     <xsl:param name="one-encounters" select="false()"/>
  157.     <!-- calculate the left over value to be passed to next recursion -->
  158.     <xsl:variable name="remainder" select="$value mod $bin"/>
  159.     <!-- calculate the value of this bit (this binary digit) -->
  160.     <xsl:variable name="this-bit" select="$value - $remainder"/>
  161.     <!-- determine whether a non-zero digit has been encountered yet -->
  162.     <xsl:variable name="one-encountered" select="boolean($one-encounters or ($this-bit > 0))"/>
  163.     <!-- only output digit if:                        -->
  164.     <!--     non-zero has already been encountered OR -->
  165.     <!--     on the last digit                        -->
  166.     <xsl:if test="$one-encountered or ($bin-power = 0)">
  167.         <xsl:value-of select="substring('01',($this-bit div $bin)+1,1)"/>
  168.     </xsl:if>
  169.     <!-- recursive call until all digits have been dealt with -->
  170.     <xsl:if test="$bin-power > 0">
  171.         <xsl:call-template name="Dec2Bin">
  172.             <xsl:with-param name="value" select="$remainder"/>
  173.             <xsl:with-param name="bin" select="$bin div 2"/>
  174.             <xsl:with-param name="bin-power" select="$bin-power - 1"/>
  175.             <xsl:with-param name="one-encounters" select="$one-encountered"/>
  176.         </xsl:call-template>
  177.     </xsl:if>
  178. </xsl:template>
  179.  
  180. <!-- ======================================================== -->
  181. <!-- Function: BinAND(<bin1>,<bin2>) => Binary string         -->
  182. <!-- Parameters:-                                             -->
  183. <!--   <bin1>  - the first binary string number to be ANDed   -->
  184. <!--   <bin2>  - the second binary string number to be ANDed  -->
  185. <xsl:template name="BinAND">
  186.     <xsl:param name="bin1" select="'0'"/>
  187.     <xsl:param name="bin2" select="'0'"/>
  188.     <!-- param used for recursion iteration -->
  189.     <xsl:param name="i" select="number(1)"/>
  190.     <xsl:variable name="max-len">
  191.         <xsl:choose>
  192.             <xsl:when test="string-length($bin1) > string-length($bin2)"><xsl:value-of select="string-length($bin1)"/></xsl:when>
  193.             <xsl:otherwise><xsl:value-of select="string-length($bin2)"/></xsl:otherwise>
  194.         </xsl:choose>
  195.     </xsl:variable>
  196.     <xsl:variable name="sbin1" select="substring(concat(substring('00000000000000000000000000000000',1,$max-len - string-length($bin1)),$bin1),$i,1)"/>
  197.     <xsl:variable name="sbin2" select="substring(concat(substring('00000000000000000000000000000000',1,$max-len - string-length($bin2)),$bin2),$i,1)"/>
  198.     <xsl:choose>
  199.         <xsl:when test="$sbin1 = '1' and $sbin2 = '1'"><xsl:text>1</xsl:text></xsl:when>
  200.         <xsl:otherwise><xsl:text>0</xsl:text></xsl:otherwise>
  201.     </xsl:choose>
  202.     <xsl:if test="$i < $max-len">
  203.         <xsl:call-template name="BinAND">
  204.             <xsl:with-param name="bin1" select="$bin1"/>
  205.             <xsl:with-param name="bin2" select="$bin2"/>
  206.             <xsl:with-param name="i" select="$i + 1"/>
  207.         </xsl:call-template>
  208.     </xsl:if>
  209. </xsl:template>
  210.  
  211. <!-- ======================================================== -->
  212. <!-- Function: BinOR(<bin1>,<bin2>) => Binary string          -->
  213. <!-- Parameters:-                                             -->
  214. <!--   <bin1>  - the first binary string number to be ORed    -->
  215. <!--   <bin2>  - the second binary string number to be ORed   -->
  216. <xsl:template name="BinOR">
  217.     <xsl:param name="bin1" select="'0'"/>
  218.     <xsl:param name="bin2" select="'0'"/>
  219.     <!-- param used for recursion iteration -->
  220.     <xsl:param name="i" select="number(1)"/>
  221.     <xsl:variable name="max-len">
  222.         <xsl:choose>
  223.             <xsl:when test="string-length($bin1) > string-length($bin2)"><xsl:value-of select="string-length($bin1)"/></xsl:when>
  224.             <xsl:otherwise><xsl:value-of select="string-length($bin2)"/></xsl:otherwise>
  225.         </xsl:choose>
  226.     </xsl:variable>
  227.     <xsl:variable name="sbin1" select="substring(concat(substring('00000000000000000000000000000000',1,$max-len - string-length($bin1)),$bin1),$i,1)"/>
  228.     <xsl:variable name="sbin2" select="substring(concat(substring('00000000000000000000000000000000',1,$max-len - string-length($bin2)),$bin2),$i,1)"/>
  229.     <xsl:choose>
  230.         <xsl:when test="$sbin1 = '1' or $sbin2 = '1'"><xsl:text>1</xsl:text></xsl:when>
  231.         <xsl:otherwise><xsl:text>0</xsl:text></xsl:otherwise>
  232.     </xsl:choose>
  233.     <xsl:if test="$i < $max-len">
  234.         <xsl:call-template name="BinOR">
  235.             <xsl:with-param name="bin1" select="$bin1"/>
  236.             <xsl:with-param name="bin2" select="$bin2"/>
  237.             <xsl:with-param name="i" select="$i + 1"/>
  238.         </xsl:call-template>
  239.     </xsl:if>
  240. </xsl:template>
  241.  
  242. <!-- ======================================================== -->
  243. <!-- Function: BinXOR(<bin1>,<bin2>) => Binary string         -->
  244. <!-- Parameters:-                                             -->
  245. <!--   <bin1>  - the first binary string number to be XORed   -->
  246. <!--   <bin2>  - the second binary string number to be XORed  -->
  247. <xsl:template name="BinXOR">
  248.     <xsl:param name="bin1" select="'0'"/>
  249.     <xsl:param name="bin2" select="'0'"/>
  250.     <!-- param used for recursion iteration -->
  251.     <xsl:param name="i" select="number(1)"/>
  252.     <xsl:variable name="max-len">
  253.         <xsl:choose>
  254.             <xsl:when test="string-length($bin1) > string-length($bin2)"><xsl:value-of select="string-length($bin1)"/></xsl:when>
  255.             <xsl:otherwise><xsl:value-of select="string-length($bin2)"/></xsl:otherwise>
  256.         </xsl:choose>
  257.     </xsl:variable>
  258.     <xsl:variable name="sbin1" select="substring(concat(substring('00000000000000000000000000000000',1,$max-len - string-length($bin1)),$bin1),$i,1)"/>
  259.     <xsl:variable name="sbin2" select="substring(concat(substring('00000000000000000000000000000000',1,$max-len - string-length($bin2)),$bin2),$i,1)"/>
  260.     <xsl:choose>
  261.         <xsl:when test="$sbin1 = '1' and $sbin2 = '1'"><xsl:text>0</xsl:text></xsl:when>
  262.         <xsl:when test="$sbin1 = '1' or $sbin2 = '1'"><xsl:text>1</xsl:text></xsl:when>
  263.         <xsl:otherwise><xsl:text>0</xsl:text></xsl:otherwise>
  264.     </xsl:choose>
  265.     <xsl:if test="$i < $max-len">
  266.         <xsl:call-template name="BinXOR">
  267.             <xsl:with-param name="bin1" select="$bin1"/>
  268.             <xsl:with-param name="bin2" select="$bin2"/>
  269.             <xsl:with-param name="i" select="$i + 1"/>
  270.         </xsl:call-template>
  271.     </xsl:if>
  272. </xsl:template>
  273.  
  274. <!-- ======================================================== -->
  275. <!-- Function: BinNOT(<bin>) => Binary string                 -->
  276. <!-- Parameters:-                                             -->
  277. <!--   <bin>  - the binary string number to be NOTed          -->
  278. <xsl:template name="BinNOT">
  279.     <xsl:param name="bin" select="'0'"/>
  280.     <xsl:param name="max-bits" select="number(32)"/>
  281.     <xsl:variable name="not1" select="translate($bin,'01','10')"/>
  282.     <xsl:value-of select="concat(substring('11111111111111111111111111111111',1,$max-bits - string-length($not1)),$not1)"/>
  283. </xsl:template>
  284.  
  285. <!-- ======================================================== -->
  286. <!-- Function: BooleanOR(<value1>,<value2>) => number         -->
  287. <!-- Parameters:-                                             -->
  288. <!--   <value1>  - the first number to be ORed                -->
  289. <!--   <value2>  - the second number to be ORed               -->
  290. <!-- NB. Only works with positive numbers!                    -->
  291. <xsl:template name="BooleanOR">
  292.     <xsl:param name="value1" select="number(0)"/>
  293.     <xsl:param name="value2" select="number(0)"/>
  294.     <!-- recurse parameters -->
  295.     <xsl:param name="bitval" select="number(2147483648)"/>
  296.     <xsl:param name="accum" select="number(0)"/>
  297.     <!-- calc bits present on values -->
  298.     <xsl:variable name="bit1" select="floor($value1 div $bitval)"/>
  299.     <xsl:variable name="bit2" select="floor($value2 div $bitval)"/>
  300.     <!-- do the OR on the bits -->
  301.     <xsl:variable name="thisbit">
  302.         <xsl:choose>
  303.             <xsl:when test="($bit1 != 0) or ($bit2 != 0)"><xsl:value-of select="$bitval"/></xsl:when>
  304.             <xsl:otherwise>0</xsl:otherwise>
  305.         </xsl:choose>
  306.     </xsl:variable>
  307.     <!-- if last recurse then output the value -->
  308.     <xsl:choose>
  309.         <xsl:when test="$bitval = 1"><xsl:value-of select="$accum + $thisbit"/></xsl:when>
  310.         <xsl:otherwise>
  311.             <!-- recurse required -->
  312.             <xsl:call-template name="BooleanOR">
  313.                 <xsl:with-param name="value1" select="$value1 mod $bitval"/>
  314.                 <xsl:with-param name="value2" select="$value2 mod $bitval"/>
  315.                 <xsl:with-param name="bitval" select="$bitval div 2"/>
  316.                 <xsl:with-param name="accum" select="$accum + $thisbit"/>
  317.             </xsl:call-template>
  318.         </xsl:otherwise>
  319.     </xsl:choose>
  320. </xsl:template>
  321.  
  322. <!-- ======================================================== -->
  323. <!-- Function: BooleanAND(<value1>,<value2>) => number        -->
  324. <!-- Parameters:-                                             -->
  325. <!--   <value1>  - the first number to be ANDed               -->
  326. <!--   <value2>  - the second number to be ANDed              -->
  327. <!-- NB. Only works with positive numbers!                    -->
  328. <xsl:template name="BooleanAND">
  329.     <xsl:param name="value1" select="number(0)"/>
  330.     <xsl:param name="value2" select="number(0)"/>
  331.     <!-- recurse parameters -->
  332.     <xsl:param name="bitval" select="number(2147483648)"/>
  333.     <xsl:param name="accum" select="number(0)"/>
  334.     <!-- calc bits present on values -->
  335.     <xsl:variable name="bit1" select="floor($value1 div $bitval)"/>
  336.     <xsl:variable name="bit2" select="floor($value2 div $bitval)"/>
  337.     <!-- do the OR on the bits -->
  338.     <xsl:variable name="thisbit">
  339.         <xsl:choose>
  340.             <xsl:when test="($bit1 != 0) and ($bit2 != 0)"><xsl:value-of select="$bitval"/></xsl:when>
  341.             <xsl:otherwise>0</xsl:otherwise>
  342.         </xsl:choose>
  343.     </xsl:variable>
  344.     <!-- if last recurse then output the value -->
  345.     <xsl:choose>
  346.         <xsl:when test="$bitval = 1"><xsl:value-of select="$accum + $thisbit"/></xsl:when>
  347.         <xsl:otherwise>
  348.             <!-- recurse required -->
  349.             <xsl:call-template name="BooleanAND">
  350.                 <xsl:with-param name="value1" select="$value1 mod $bitval"/>
  351.                 <xsl:with-param name="value2" select="$value2 mod $bitval"/>
  352.                 <xsl:with-param name="bitval" select="$bitval div 2"/>
  353.                 <xsl:with-param name="accum" select="$accum + $thisbit"/>
  354.             </xsl:call-template>
  355.         </xsl:otherwise>
  356.     </xsl:choose>
  357. </xsl:template>
  358.  
  359. <!-- ======================================================== -->
  360. <!-- Function: BooleanXOR(<value1>,<value2>) => number        -->
  361. <!-- Parameters:-                                             -->
  362. <!--   <value1>  - the first number to be XORed               -->
  363. <!--   <value2>  - the second number to be XORed              -->
  364. <!-- NB. Only works with positive numbers!                    -->
  365. <xsl:template name="BooleanXOR">
  366.     <xsl:param name="value1" select="number(0)"/>
  367.     <xsl:param name="value2" select="number(0)"/>
  368.     <!-- recurse parameters -->
  369.     <xsl:param name="bitval" select="number(2147483648)"/>
  370.     <xsl:param name="accum" select="number(0)"/>
  371.     <!-- calc bits present on values -->
  372.     <xsl:variable name="bit1" select="floor($value1 div $bitval)"/>
  373.     <xsl:variable name="bit2" select="floor($value2 div $bitval)"/>
  374.     <!-- do the XOR on the bits -->
  375.     <xsl:variable name="thisbit">
  376.         <xsl:choose>
  377.             <xsl:when test="(($bit1 != 0) and ($bit2 = 0)) or (($bit1 = 0) and ($bit2 != 0))"><xsl:value-of select="$bitval"/></xsl:when>
  378.             <xsl:otherwise>0</xsl:otherwise>
  379.         </xsl:choose>
  380.     </xsl:variable>
  381.     <!-- if last recurse then output the value -->
  382.     <xsl:choose>
  383.         <xsl:when test="$bitval = 1"><xsl:value-of select="$accum + $thisbit"/></xsl:when>
  384.         <xsl:otherwise>
  385.             <!-- recurse required -->
  386.             <xsl:call-template name="BooleanXOR">
  387.                 <xsl:with-param name="value1" select="$value1 mod $bitval"/>
  388.                 <xsl:with-param name="value2" select="$value2 mod $bitval"/>
  389.                 <xsl:with-param name="bitval" select="$bitval div 2"/>
  390.                 <xsl:with-param name="accum" select="$accum + $thisbit"/>
  391.             </xsl:call-template>
  392.         </xsl:otherwise>
  393.     </xsl:choose>
  394. </xsl:template>
  395.  
  396. </xsl:stylesheet>