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

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