[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] Bitwise Operations:More efficient solution?


Subject: Re: [xsl] Bitwise Operations:More efficient solution?
From: Wolfgang Laun <wolfgang.laun@xxxxxxxxx>
Date: Wed, 16 Feb 2011 17:03:37 +0100

I think its easy to write functions such as this one:

<xsl:function name="wl:bitand" as="xsd:integer">
  <xsl:param name="a" as="xsd:integer"/>
  <xsl:param name="b" as="xsd:integer"/>
  <xsl:param name="n" as="xsd:integer"/>
  <xsl:choose>
    <xsl:when test="$n = 0">
      <xsl:value-of select="0"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:variable name="x" as="xsd:integer" select="($a mod 2)*($b mod
2)"/>
      <xsl:value-of select="2* wl:bitand($a idiv 2, $b idiv 2, $n - 1) +
$x"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:function>

And call it like this
 <xsl:value-of select="wl:bitand(@a, @b, 8)"/>

or wrap this in a function supplying the initial 8.

-W





On 16 February 2011 16:45, Eliot Kimber <ekimber@xxxxxxxxxxxx> wrote:
>
> Cool, that helps.
>
> This is specific to UTF-8 decoding, but I sort of wanted to have generic
> bitwise operations. I was actually surprised those aren't in the base
> operators but whatever.
>
> Cheers,
>
> E.
> On 2/16/11 9:15 AM, "Chris Maloney" <voldrani@xxxxxxxxx> wrote:
>
> > [Sorry, hit the "Send" button by mistake.]
> >
> > I thought of some more optimizations on the way to work this morning.
> > First of all, you can simplify your expressions:
> >
> >   ....
> >     <xsl:variable name="byte1Bit7"
> >                   select="if ($byte1 > 127) then 1 else 0"
> >                   as="xs:integer"/>
> >     <xsl:variable name="byte1Bit6"
> >                   select="if ($byte1 mod 128 > 63) then 1 else 0"
> >                   as="xs:integer"/>
> >     <xsl:variable name="byte1Bit5"
> >                   select="if ($byte1 mod 64 > 31) then 1 else 0"
> >                   as="xs:integer"/>
> >     <xsl:variable name="byte1Bit4"
> >                   select="if ($byte1 mod 32 > 15) then 1 else 0"
> >                   as="xs:integer"/>
> >     <xsl:variable name="byte1Bit3"
> >                   select="if ($byte1 mod 16 > 7) then 1 else 0"
> >                   as="xs:integer"/>
> >     <xsl:variable name="byte1Bit2"
> >                   select="if ($byte1 mod 8 > 3) then 1 else 0"
> >                   as="xs:integer"/>
> >     <xsl:variable name="byte1Bit1"
> >                   select="if ($byte1 mod 4 > 1) then 1 else 0"
> >                   as="xs:integer"/>
> >     <xsl:variable name="byte1Bit0"
> >                   select="$byte1 mod 2"
> >                   as="xs:integer"/>
> >     ...
> >
> > Then, it occurred to me that if you're doing bitwise-and specifically
> > for utf-8 conversion, then you can optimize this quite a bit.  The
> > ANDing needed by utf-8 conversion is never to a random bit pattern,
> > but instead to fixed bit-masks, where the bits are always grouped
> > together.  So, for example, you could make a specific function to AND
> > with 0x3F:
> >
> >   <xsl:function name="relpath:bitwiseAnd3F" as="xs:integer">
> >       <xsl:param name="arg" as="xs:integer"/>
> >       <xsl:variable name='result'
> >                     as='xs:integer'
> >                     select="$arg mod 64"/>
> >       <xsl:sequence select="$result"/>
> >   </xsl:function>
> >
> > and its complement to AND with 0xC0:
> >
> >   <xsl:function name="relpath:bitwiseAndC0" as="xs:integer">
> >       <xsl:param name="byte" as="xs:integer"/>
> >       <xsl:variable name='result'
> >                     as='xs:integer'
> >                     select="($byte - $byte mod 64) / 64"/>
> >       <xsl:sequence select="$result"/>
> >   </xsl:function>
> >
> > Cheers!
> >
> >
> > On Tue, Feb 15, 2011 at 5:41 PM, Eliot Kimber <ekimber@xxxxxxxxxxxx>
wrote:
> >> I have implemented UTF-8 URI decoding in XSLT 2. It required that I
> >> implement left-shift and bitwise AND operations. Left-shift is easy but
> >> bitwise AND is a little more involved. My solution is below, but I'm
> >> wondering if there's a more elegant and/or efficient way to do this?
> >>
> >> My approach was based on info from Ken Holman's site that shows how to
> >> calculate each bit of the byte. I do that and then sum the result of
> >> multiplying the AND of each bit pair times the appropriate power of two.
> >>
> >>  <xsl:function name="relpath:bitwiseAnd" as="xs:integer">
> >>    <xsl:param name="byte1" as="xs:integer"/>
> >>    <xsl:param name="byte2" as="xs:integer"/>
> >>
> >>    <xsl:variable name="byte1Bit7" select="if (($byte1 mod 256) - ($byte1
> >> mod 128) > 0) then 1 else 0" as="xs:integer"/>
> >>    <xsl:variable name="byte1Bit6" select="if (($byte1 mod 128) - ($byte1
> >> mod 64) > 0) then 1 else 0" as="xs:integer"/>
> >>    <xsl:variable name="byte1Bit5" select="if (($byte1 mod 64)  - ($byte1
> >> mod 32) > 0) then 1 else 0" as="xs:integer"/>
> >>    <xsl:variable name="byte1Bit4" select="if (($byte1 mod 32)  - ($byte1
> >> mod 16) > 0) then 1 else 0" as="xs:integer"/>
> >>    <xsl:variable name="byte1Bit3" select="if (($byte1 mod 16)  - ($byte1
> >> mod 8) > 0) then 1 else 0" as="xs:integer"/>
> >>    <xsl:variable name="byte1Bit2" select="if (($byte1 mod 8)   - ($byte1
> >> mod 4) > 0) then 1 else 0" as="xs:integer"/>
> >>    <xsl:variable name="byte1Bit1" select="if (($byte1 mod 4)   - ($byte1
> >> mod 2) > 0) then 1 else 0" as="xs:integer"/>
> >>    <xsl:variable name="byte1Bit0" select="if (($byte1 mod 2)  > 0) then
1
> >> else 0" as="xs:integer"/>
> >>
> >>    <xsl:variable name="byte2Bit7" select="if (($byte2 mod 256) - ($byte2
> >> mod 128) > 0) then 1 else 0" as="xs:integer"/>
> >>    <xsl:variable name="byte2Bit6" select="if (($byte2 mod 128) - ($byte2
> >> mod 64) > 0) then 1 else 0" as="xs:integer"/>
> >>    <xsl:variable name="byte2Bit5" select="if (($byte2 mod 64)  - ($byte2
> >> mod 32) > 0) then 1 else 0" as="xs:integer"/>
> >>    <xsl:variable name="byte2Bit4" select="if (($byte2 mod 32)  - ($byte2
> >> mod 16) > 0) then 1 else 0" as="xs:integer"/>
> >>    <xsl:variable name="byte2Bit3" select="if (($byte2 mod 16)  - ($byte2
> >> mod 8) > 0) then 1 else 0" as="xs:integer"/>
> >>    <xsl:variable name="byte2Bit2" select="if (($byte2 mod 8)   - ($byte2
> >> mod 4) > 0) then 1 else 0" as="xs:integer"/>
> >>    <xsl:variable name="byte2Bit1" select="if (($byte2 mod 4)   - ($byte2
> >> mod 2) > 0) then 1 else 0" as="xs:integer"/>
> >>    <xsl:variable name="byte2Bit0" select="if (($byte2 mod 2)  > 0) then
1
> >> else 0" as="xs:integer"/>
> >>
> >>    <xsl:variable name="result" as="xs:integer"
> >>      select="
> >>      (128 * $byte2Bit7 * $byte1Bit7) +
> >>      (64 * $byte2Bit6 * $byte1Bit6) +
> >>      (32 * $byte2Bit5 * $byte1Bit5) +
> >>      (16 * $byte2Bit4 * $byte1Bit4) +
> >>      (8* $byte2Bit3 * $byte1Bit3) +
> >>      (4 * $byte2Bit2 * $byte1Bit2) +
> >>      (2 * $byte2Bit1 * $byte1Bit1) +
> >>      (1 * $byte2Bit0 * $byte1Bit0)
> >>      "
> >>    />
> >>    <xsl:sequence select="$result"/>
> >>  </xsl:function>
> >>
> >> Cheers,
> >>
> >> E.
> >> --
> >> Eliot Kimber
> >> Senior Solutions Architect
> >> "Bringing Strategy, Content, and Technology Together"
> >> Main: 512.554.9368
> >> www.reallysi.com
> >> www.rsuitecms.com
> >
>
> --
> Eliot Kimber
> Senior Solutions Architect
> "Bringing Strategy, Content, and Technology Together"
> Main: 512.554.9368
> www.reallysi.com
> www.rsuitecms.com


Current Thread
Keywords