• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

Bitwise problem

Status
Not open for further replies.
Level 23
Joined
Feb 6, 2014
Messages
2,466
Does anyone know how to use this snippet or this one? Could provide me some examples pls? T_T
I haven't use those snippets you provided but my guess (based on a quick look) is that those integers will be converted into binary and then the operation will be done.
For example, OR(42, 69) will result to OR(0101010, 1000101) -> 1101111 (bin) -> 111 (dec).

EDIT: You asked for OR/XOR example not AND.
 
Last edited:
Level 9
Joined
Jun 21, 2012
Messages
431
Well the real doubt:

I have this code, it works fine with operators AND/NOT, I have tried to implement OR/XOR operators and I have not been successful... How can I make the system work with these? set unitFilter = UF_AND_ALIVE + UF_OR_ENEMY + UF_AND_STRUCTURE //etc...
JASS:
if(this>=0x8)then
    if(not $BOOLEAN$)then
        return true
    endif
    set this=this-0x8
endif
if(this>=0x4)then
    if($BOOLEAN$)then
        return true
    endif
    set this=this-0x4
endif
if(this>=0x2)then
    if($BOOLEAN$)then
        return false
    endif
    set this=this-0x2
endif
if(this>=0x1)then
    if(not $BOOLEAN$)then
        return false
    endif
    set this=this-0x1
endif
 
Look at the one Bannar posted starting from the 32 bit variant and trace it down to the byte variants.


32 splits it into 4 bytes
4 bytes look at the hexadecimal digits in each byte and & these together, then recombine.
When it performs the actual & calculation on the digits, it does it via a lookup table.

Here is an example of some values from the lookup table for and. You read this by looking at the index and treating it as the two values in the operation. Pretty easy, eh? 0x41 represents 4 & 1. 0x44 represents 4 & 4. The result of 4 & 4 is 4.

JASS:
            set andData[0x41] = 0x0
            set andData[0x42] = 0x0
            set andData[0x43] = 0x0
            set andData[0x44] = 0x4

Here is how that array is used

JASS:
andData[sub1 * 0x10 + sub2]

Where sub1 and sub2 represent the two hexadecimal digits.

Now we go a step further and & two bytes together

AND(lbyte[byte1], lbyte[byte2]) * 0x10 + sbyte.AND(rbyte[byte1], rbyte[byte2])

Left digits are &'d together and right digits are &'d together. The results are combined into a single byte.

Now let's look at 4 bytes.

JASS:
AND(b1*128 + int1/0x1000000, b2*128 + int2/0x1000000)*0x1000000 + /*
                */ AND((int1 - int1/0x1000000*0x1000000)/0x10000, (int2 - int2/0x1000000*0x1000000)/0x10000) * 0x10000 + /*
                */ AND((int1 - int1/0x10000*0x10000)/0x100, (int2 - int2/0x10000*0x10000)/0x100) * 0x100 + /*
                */ AND(int1 - int1/0x100*0x100, int2 - int2/0x100*0x100)

The two numbers are bring broke up into 4 bytes, hence the 4 calls to AND. b1 and b2 represent the leftmost bits. The top bit has to be removed so that the number is unsigned. The top bits are added back in in that first AND operation. The 128 represents 2^7, or 7 bits out of the 8 in the byte, the 8th being the one added back in : ).



All of the operations work the same way.


The script from wc3c does the same thing, but inlines all of the code instead from the lookup table and goes digit by digit.


Both are going to have those same 8 lookups. I chose not to inline it to cut down on modulo spam. I also have support for signed integers, which the one from wc3c is missing. This adds a little extra code and math. Both do the same exact thing : p.



From wc3c, here are where your actual calculations are taken place. i is the current byte and every byte from 0 to 255 is iterated over. This performs the operation across each individual bit mathematically.


Here are the individual bit calculations as per the script

AND is a*b
OR is a + b - a*b
XOR is a + b - 2*a*b

Perform these 4 times per byte (once for each binary digit) and add them together to get the resulting AND/OR/XOR hexadecimal digit operation (each byte represents an operation between two half bytes, aka one hexadecimal digit). Store results into a lookup table to shortcut byte and 32-bit operations. Mag and I opted to plug values in directly : p.

JASS:
  // 0x100 = AND
  // 0x200 = OR
  // 0x300 = XOR

   set a = i / 16
   set b = i - a * 16
   set ta = a - (a / 2) * 2
   set tb = b - (b / 2) * 2
   set bintable[0x100 + i] = ta * tb
   set bintable[0x200 + i] = ta + tb - ta * tb
   set bintable[0x300 + i] = ta + tb - 2 * ta * tb
   set a = a / 2
   set b = b / 2
   set ta = a - (a / 2) * 2
   set tb = b - (b / 2) * 2
   set bintable[0x100 + i] = bintable[0x100 + i] + 2 * (ta * tb)
   set bintable[0x200 + i] = bintable[0x200 + i] + 2 * (ta + tb - ta * tb)
   set bintable[0x300 + i] = bintable[0x300 + i] + 2 * (ta + tb - 2 * ta * tb)
   set a = a / 2
   set b = b / 2
   set ta = a - (a / 2) * 2
   set tb = b - (b / 2) * 2
   set bintable[0x100 + i] = bintable[0x100 + i] + 4 * (ta * tb)
   set bintable[0x200 + i] = bintable[0x200 + i] + 4 * (ta + tb - ta * tb)
   set bintable[0x300 + i] = bintable[0x300 + i] + 4 * (ta + tb - 2 * ta * tb)
   set ta = a / 2
   set tb = b / 2
   set bintable[0x100 + i] = bintable[0x100 + i] + 8 * (ta * tb)
   set bintable[0x200 + i] = bintable[0x200 + i] + 8 * (ta + tb - ta * tb)
   set bintable[0x300 + i] = bintable[0x300 + i] + 8 * (ta + tb - 2 * ta * tb)
 
Last edited:
Status
Not open for further replies.
Top