Subject: Re: [xsl] Bitwise Operations:More efficient solution? From: Eliot Kimber <ekimber@xxxxxxxxxxxx> Date: Fri, 18 Feb 2011 10:01:41 -0600 |
Thanks, That is much more elegant. I should have thought of using a recursive function. Cheers, E. On 2/16/11 10:03 AM, "Wolfgang Laun" <wolfgang.laun@xxxxxxxxx> wrote: > 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 > -- Eliot Kimber Senior Solutions Architect "Bringing Strategy, Content, and Technology Together" Main: 512.554.9368 www.reallysi.com www.rsuitecms.com
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Bitwise Operations:More e, Wolfgang Laun | Thread | [xsl] Newbie cannot find syntax err, thehulk |
AW: [xsl] multiple passes dont work, Szabo, Patrick \(LNG | Date | Re: [xsl] Q on XSLT number calculat, Hermann Stamm-Wilbra |
Month |