FW: Re: Hexadecimal Arithmetic

Subject: FW: Re: Hexadecimal Arithmetic
From: Nate Austin <naustin@xxxxxxxxxxxxxxx>
Date: Thu, 31 Aug 2000 17:14:43 -0500
Hmmm... it would help if I remembered to paste it in there.  Doh!

This template adds hex values F0F0F0F0 and 0F0F0F0F to come up with FFFFFFFF
as it should be.  This was tested with Xalan 1.0.1.

-Nate

<?xml version="1.0"?>
<xsl:transform version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
                             
  <xsl:output method="text"/>
  
  <xsl:template match="/">
    <xsl:call-template name="hexMath">
      <xsl:with-param name="op1" select="'F0F0F0F0'"/>
      <xsl:with-param name="oper" select="'+'"/>
      <xsl:with-param name="op2" select="'0F0F0F0F'"/>
    </xsl:call-template>
  </xsl:template>
  
  <xsl:template name="hexMath">
    <xsl:param name="op1"/>
    <xsl:param name="oper"/>
    <xsl:param name="op2"/>
    <xsl:variable name="numOp1">
      <xsl:call-template name="hexToDec">
        <xsl:with-param name="hexVal" select="$op1"/>
        <xsl:with-param name="decVal" select="0"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="numOp2">
      <xsl:call-template name="hexToDec">
        <xsl:with-param name="hexVal" select="$op2"/>
        <xsl:with-param name="decVal" select="0"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:choose>
      <xsl:when test="$oper = '+'">
        <xsl:variable name="res">
          <xsl:call-template name="decToHex">
            <xsl:with-param name="decVal" select="$numOp1 + $numOp2"/>
          </xsl:call-template>
        </xsl:variable>
        <xsl:value-of select="$res"/>
      </xsl:when>
      <xsl:when test="$oper = '-'">
        <xsl:variable name="res">
          <xsl:call-template name="decToHex">
            <xsl:with-param name="decVal" select="$numOp1 - $numOp2"/>
          </xsl:call-template>
        </xsl:variable>
        <xsl:value-of select="$res"/>
      </xsl:when>
      <xsl:when test="$oper = '*'">
        <xsl:variable name="res">
          <xsl:call-template name="decToHex">
            <xsl:with-param name="decVal" select="$numOp1 * $numOp2"/>
          </xsl:call-template>
        </xsl:variable>
        <xsl:value-of select="$res"/>
      </xsl:when>
      <xsl:when test="$oper = 'div'">
        <xsl:variable name="res">
          <xsl:call-template name="decToHex">
            <xsl:with-param name="decVal" select="$numOp1 div $numOp2"/>
          </xsl:call-template>
        </xsl:variable>
        <xsl:value-of select="$res"/>
      </xsl:when>
      <xsl:when test="$oper = 'mod'">
        <xsl:variable name="res">
          <xsl:call-template name="decToHex">
            <xsl:with-param name="decVal" select="$numOp1 mod $numOp2"/>
          </xsl:call-template>
        </xsl:variable>
        <xsl:value-of select="$res"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:message>Error!  Unknown operation!</xsl:message>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  
  <xsl:template name="singleDecToHex">
    <xsl:param name="num"/>
    <xsl:choose>
      <xsl:when test="$num &lt; 16 and $num &gt;= 0">
        <xsl:variable name="table" select="'0123456789ABCDEF'"/>
        <xsl:value-of select="substring($table,$num + 1,1)"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:message>Number to convert to hexadecimal out of
range</xsl:message>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  
  <xsl:template name="singleHexToDec">
    <xsl:param name="hex"/>
    <xsl:variable name="table" select="'0123456789ABCDEF'"/>
    <xsl:value-of select="string-length(substring-before($table,$hex))"/>
  </xsl:template>
  
  <xsl:template name="findPower">
    <xsl:param name="value"/>
    <xsl:param name="currPower"/>
    <xsl:param name="multiplier"/>
    <xsl:param name="accumulator"/>
    <xsl:choose>
      <xsl:when test="$value &lt; $accumulator">
        <xsl:value-of select="$accumulator div $multiplier"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:call-template name="findPower">
          <xsl:with-param name="value" select="$value"/>
          <xsl:with-param name="currPower" select="$currPower + 1"/>
          <xsl:with-param name="multiplier" select="$multiplier"/>
          <xsl:with-param name="accumulator" select="$accumulator *
$multiplier"/>
        </xsl:call-template>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  
  <xsl:template name="decToHex">
    <xsl:param name="decVal"/>
    <xsl:variable name="power">
      <xsl:call-template name="findPower">
        <xsl:with-param name="value" select="$decVal"/>
        <xsl:with-param name="currPower" select="0"/>
        <xsl:with-param name="multiplier" select="16"/>
       <xsl:with-param name="accumulator" select="1"/> <!-- everything to 0
power is 1 -->
      </xsl:call-template>
    </xsl:variable>
    <xsl:call-template name="decToHexIter">
      <xsl:with-param name="decVal" select="$decVal"/>
      <xsl:with-param name="hexVal" select="''"/>
      <xsl:with-param name="power" select="$power"/>
    </xsl:call-template>
  </xsl:template>
  
  <xsl:template name="decToHexIter">
    <xsl:param name="decVal"/>
    <xsl:param name="hexVal"/>
    <xsl:param name="power"/>
    <xsl:choose>
      <xsl:when test="$decVal &gt; 0">
        <xsl:variable name="currDecVal" select="($decVal - ($decVal mod
$power)) div $power"/>
        <xsl:variable name="hexDigit">
          <xsl:call-template name="singleDecToHex">
            <xsl:with-param name="num" select="$currDecVal"/>
          </xsl:call-template>
        </xsl:variable>
        <xsl:call-template name="decToHexIter">
          <xsl:with-param name="decVal" select="$decVal - ($currDecVal *
$power)"/>
          <xsl:with-param name="hexVal" select="concat($hexVal,$hexDigit)"/>
          <xsl:with-param name="power" select="$power div 16"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$hexVal"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  
  <xsl:template name="raiseToPower">
    <xsl:param name="number"/>
    <xsl:param name="power"/>
    <xsl:call-template name="raiseToPowerIter">
      <xsl:with-param name="multiplier" select="$number"/>
      <xsl:with-param name="accumulator" select="1"/>
      <xsl:with-param name="reps" select="$power"/>
    </xsl:call-template>
  </xsl:template>
  
  <xsl:template name="raiseToPowerIter">
    <xsl:param name="multiplier"/>
    <xsl:param name="accumulator"/>
    <xsl:param name="reps"/>
    <xsl:choose>
      <xsl:when test="$reps &gt; 0">
        <xsl:call-template name="raiseToPowerIter">
          <xsl:with-param name="multiplier" select="$multiplier"/>
          <xsl:with-param name="accumulator" select="$accumulator *
$multiplier"/>
          <xsl:with-param name="reps" select="$reps - 1"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$accumulator"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  
  <xsl:template name="hexToDec">
    <xsl:param name="hexVal"/>
    <xsl:param name="decVal"/>
    <xsl:variable name="hexLength" select="string-length($hexVal)"/>
    <xsl:choose>
      <xsl:when test="$hexLength &gt; 0">
        <xsl:variable name="hexPos">
          <xsl:call-template name="singleHexToDec">
            <xsl:with-param name="hex" select="substring($hexVal,1,1)"/>
          </xsl:call-template>
        </xsl:variable>
        <xsl:variable name="addToDec">
          <xsl:call-template name="raiseToPower">
            <xsl:with-param name="number" select="16"/>
            <xsl:with-param name="power" select="$hexLength - 1"/>
          </xsl:call-template>
        </xsl:variable>
        <xsl:call-template name="hexToDec">
          <xsl:with-param name="hexVal" select="substring($hexVal,2)"/>
          <xsl:with-param name="decVal" select="$decVal + ($addToDec *
$hexPos)"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$decVal"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  
</xsl:transform>

-----Original Message-----
From: Nate Austin 
Sent: Thursday, August 31, 2000 5:09 PM
To: 'xsl-list@xxxxxxxxxxxxxxxx'
Subject: Re: Hexadecimal Arithmetic


Maulik -

It gets a little ugly, but what follows converts from hex to dec, does the
operation, then converts back.  As an aside, I've never had the need to look
before now, but I didn't find an operator for n to the x power (generally
n^x) ... am I missing it somewhere in the specs or does it actually not
exist?  If one exists, this can be slightly simplified by removing that
recursive template.  This would probably be quite a bit less verbose with a
hook into an extension function also, but until those are standardized in
1.1 I'll stick with this.

Hope this helps!

-Nate

>Date: Thu, 31 Aug 2000 09:45:05 -0500
>From: "Maulik Modi" <mxmodi@xxxxxxxxxxxxxxx>
>Subject: Hexadecimal Arithmetic
>
>Hi,
>
>I have the following snippet of my XML data:
><root>
><parent level="1">
><child1>some text</child1>
><child2>some more text</child2>
><parent>
><parent level="2">
><child1>text</child1>
><child2>different text</child2>
></parent>
>....
></root>
>
>I want to present this in a table and that's done. Now I want to color code
each
> table row depending on the value of the "level" attribute. That's done.
Now I
>want to give each row a different gradient of the same color depending on
the
>value of the "level". The value of the level ranges from 1-10. I wanted to
take
>this and use
>it with hexadecimal arithmetic. Does anyone know how?
>
>I am getting greedy now, but it would be really nice if I could do this
>dynamically as I foresee that my XML data will not be static.
>
>Any help is appreciated.
>
>Maulik


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread