Home > Mobile >  How can optimize this boolean function for speed?
How can optimize this boolean function for speed?

Time:07-17

I have 2 unsigned 8 bit integers a,b.

The result of the calculation is either -1 or 1.

I work with the binary representation of the integers a,b

a=173;
b=154;
bina = "10101101"
binb = "10011010"

first, the common bits on both integers a XOR b are eliminated:

aANb = a & (a ^ b)
bANa = b & (a ^ b)
aANb = 00100101
bANa = 00010010

For each 1-bit in bANa the number of 1-bits in aANb to the right of the bit are counted.

The sum of the number of bits for each bit in bANa is then calculated.

For example there are 2 1-bits in bANa. The leftmost bit has 2 1-bits to the right of it in aANb:

bANa = 0001  0001
aANb = 0010  0101 -> 2 bits

The second 1-bit in bANa has 1 1-bit to the right of it in aANb:

bANa = 0001001  0
aANb = 0010010  1 -> 1 bit

The sum is then found for these values:

sum = 2 1 = 3

If sum is even, return 1, and if it is odd, return -1

I target x86, but I want it to be open source, so I don't know in which CPU it will run.

I hope it can be speeded up. Notice that if aANb has pairs of contiguous 1, they do not change the result.

Maybe the string of bits can be decomposed in smaller chunks, with tabulated results.

This is my code (is my first ever C# code, I never wrote C# before)

int a = 173;
int b = 154;
int sum = 0;
int aANb = 0;
int bANa = 0;
for (int i = 0; i < 8; i  )
{
    aANb = a & (a ^ b);
    bANa = b & (a ^ b);

    if ((bANa >> i) % 2 == 1)
    {
        for (int j = i; j < 8; j  )
        {
            sum  = (aANb >> j) % 2;
        }
    }
}
int[] answer = { 1, -1 };
string result = $"a={a}\n"  
                $"b={b}\n"  
                $"binary a={Convert.ToString(a, 2).PadLeft(8, '0')}\n"  
                $"binary b={Convert.ToString(b, 2).PadLeft(8, '0')}\n"  
                $"    aANb={Convert.ToString(aANb,2).PadLeft(8, '0')}\n"  
                $"    bANa={Convert.ToString(bANa,2).PadLeft(8, '0')}\n"  
                $"sum={sum}\n"  
                $"result={answer[sum % 2]}";
System.Console.WriteLine(result);

This should output

a = 173
b = 154
binary a=10101101
binary b=10011010
    aANb=00100101
    bANa=00010010
sum=3
result=-1
>>>result=-1

CodePudding user response:

First: aANb and bANa need to be calculated only once outside of the loop.

Second: you don't have to calculate the sum since adding an odd number to sum will invert the "odd" state you can use only an XOR operation:

int a = 173;
int b = 154;
int odd = 0;
int aANb =  a & ~b;
int bANa = b & ~a;
for (int i = 0; i < 8; i  )
{
    if ((bANa >> i) % 2 == 1)
    {
        for (int j = i; j < 8; j  )
        {
            odd ^= (bANa >> j) ; 
        }
    }
}

result:

$"result={answer[odd%2]}";
  • Related