XOR operation in C++ - c++

How does the XOR logical operator work on more than two values?
For instance, in an operation such as 1 ^ 3 ^ 7?
0 0 0 1 // 1
0 0 1 1 // 3
0 1 1 1 // 7
__
0 1 0 1 // 5
for some reason yields 0 1 0 1, where as it should have, as I thought, yielded: 0 1 0 0, since XOR is only true when strictly one of the operands is true.

Because of the operator precedence and because the xor is a binary operator, which in this case is left-to-right.
First 1 ^ 3 is evaluated
0 0 0 1 // 1
0 0 1 1 // 3
-------
0 0 1 0 // 2
The result is 2, then this number is the first operand of the last xor operation (2 ^ 7)
0 0 1 0 // 2
0 1 1 1 // 7
-------
0 1 0 1 // 5
The result is 5.

1 ^ 3 ^ 7 is not a function of three arguments, it is: (1 ^ 3) ^ 7 which equals 2 ^ 7 which equals 5.
Though actually this ^ operator is associative: each bit in the result will be set if and only if an odd number of the operands had the bit set.

XOR works bitwise, XORing each position separately
XOR is commutative, so a^b = b^a
XOR is associative, so (a^b)^c = a^(b^c)
Using this, a human can count the number of ones in a given position and the result bit is set exactly for an odd number of ones in the given position of the operands.
Counting ones yields (0101)binary=5

The expression is parsed as (1 ^ 3) ^ 7 so you first get
0001 ^ 0011
which is 0010. The rest is
0010 ^ 0111
which is 0101

^ is a binary operator. It doesn't work on all three numbers at once, i.e. it's (1^3)^7, which is:
1 ^ 3 == 2
2 ^ 7 == 5

Related

C++ how would you find a number with the most similar bits in N integers?

For example say I have 3 integers 18 9 21
those 3 integers in binary : 10010, 10001, 10101
and say there's a number x I want that number to basically be the most similar bits for example the first digit of each number is 1 so x will start off as "1.....". The second digit of all three numbers is zero, so it will be "10...". The third digit is a mix: We have a 0,0 and a 1. but we have more zeros than 1's so x will be "100.." etc.
Is there any way to do this? I've been looking at bitwise operators and I'm just not sure how to do this? Because bitwise and doesn't really work on three numbers like this because if it sees even just one zero it will just return 0
I would simply add the bits if I were you: imagine the numbers: 17, 9 and 21, and let's write them in binary:
17 : 10001
9 : 01001
21 : 10101
Put this in a "table" and sum your binary digits:
1 0 0 0 1
0 1 0 0 1
1 0 1 0 1
2 1 1 0 3
... and then you say "When I have 0 or 1, I put '0', when 2 or 3, I put '1'", then you get:
1 0 0 0 1
=> your answer becomes "10001" which equals 17.

Regular Expression to match few characters from a string

I am trying to find a string within another string. However, I am trying to match even if one or more character is not matching.
Let me explain with an example :
Let's say I have a string 'abcdefghij'. Now if the string to match is 'abcd',
I could write strfind('abcdefghij', 'abc')
Now, I have a string 'adcf'. Notice that, there is a mismatch in two characters, I would consider it as a match.
Any idea how to do it ?
I know, this is not the most optimal code.
Example :
a='abcdefghijk';
b='xbcx'
c='abxx'
d='axxd'
e='abcx'
f='xabc'
g='axcd'
h='abxd'
i ='abcd'
All these strings should match with a. I hope this example makes it more clear. The idea is, if there is a mismatch of 1 or 2 characters also, it should be considered as a match.
You could do it like this:
A = 'abcdefghij'; % Main string
B = 'adcf'; % String to be found
tolerance = 2; % Maximum number of different characters to tolerate
nA = numel(A);
nB = numel(B);
pos = find(sum(A(mod(cumsum([(1:nA)' ones(nA, nB - 1)], 2) - 1, nA) + 1) == repmat(B, nA, 1), 2) >= nB - tolerance);
In this case it will return pos = [1 3]'; because "adcf" can be matched on the first position (matching "a?c?") and on the third position (matching "?d?f")
Explanation:
First, we take the sizes of A and B
Then, we create the matrix [(1:nA)' ones(nA, nB - 1)], which gives us this:
Output:
1 1 1 1
2 1 1 1
3 1 1 1
4 1 1 1
5 1 1 1
6 1 1 1
7 1 1 1
8 1 1 1
9 1 1 1
10 1 1 1
We perform a cumulative sum to the right, using cumsum, to achieve this:
Output:
1 2 3 4
2 3 4 5
3 4 5 6
4 5 6 7
5 6 7 8
6 7 8 9
7 8 9 10
8 9 10 11
9 10 11 12
10 11 12 13
And use the mod function so each number is between 1 and nA, like this:
Output:
1 2 3 4
2 3 4 5
3 4 5 6
4 5 6 7
5 6 7 8
6 7 8 9
7 8 9 10
8 9 10 1
9 10 1 2
10 1 2 3
We then use that matrix as an index for the A matrix.
Output:
abcd
bcde
cdef
defg
efgh
fghi
ghij
hija
ijab
jabc
Note this matrix has all possible substrings of A with size nB.
Now we use repmat to replicate B down, 'nA rows'.
Output:
adcf
adcf
adcf
adcf
adcf
adcf
adcf
adcf
adcf
adcf
And perform a direct comparison:
Output:
1 0 1 0
0 0 0 0
0 1 0 1
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
Summing to the right give us this:
Output:
2
0
2
0
0
0
0
0
0
0
Which are the number of character matches on each possible substring.
To finish, we use find to select the indexes of the matches within our tolerance.
In your code
c=a-b is not valid (Matrix dimensions not same)
If you need at least one match, not in order, (as your example says), you can have something like this :-
>> a='abcdefgh';
>> b='adcf';
>> sum(ismember(a,b)) ~= 0
ans =
1

Bitwise operation to get 1 if both are 0

I'd need to perform a bitwise operation (or a serie) so that:
0 1 = 0
1 1 = 1
1 0 = 0
so far AND (&) works fine but I also need that
0 0 = 1
and here AND (&) is not the correct one.
I'm using it in a jquery grep function that reads:
jQuery.grep(json, function (e, index) {
return (e.value & (onoff << 3)) != 0;
});
where onoff could be either 1 or 0 and e.value is a representation of a 4 bits string (i.e. could be "1001"). In this above example I'm testing first bit on the left (<< 3).
Can this be done with a serie of AND, OR, XOR?
This is just XNOR(a, b), which is equal to NOT(XOR(a, b)), i.e. exclusive OR with the output inverted. In C and C-like languages this would be:
!(a ^ b)
or in your specific case:
return !((e.value >> 3) ^ onoff);
Having said that, you could just test for equality:
return (e.value >> 3) == onoff;
This looks roughly like XOR which has the following results table:
0 0 = 0
0 1 = 1
1 0 = 1
1 1 = 0
Now you want to have the opposite, meaning that you want 1 if both inputs are the same value. And this leads us to NOT XOR
0 0 = 1
0 1 = 0
1 0 = 0
1 1 = 1

How can I count amount of sequentially set bits in a byte from left to right until the first 0?

I'm not good in English, I can't ask it better, but please below:
if byte in binary is 1 0 0 0 0 0 0 0 then result is 1
if byte in binary is 1 1 0 0 0 0 0 0 then result is 2
if byte in binary is 1 1 1 0 0 0 0 0 then result is 3
if byte in binary is 1 1 1 1 0 0 0 0 then result is 4
if byte in binary is 1 1 1 1 1 0 0 0 then result is 5
if byte in binary is 1 1 1 1 1 1 0 0 then result is 6
if byte in binary is 1 1 1 1 1 1 1 0 then result is 7
if byte in binary is 1 1 1 1 1 1 1 1 then result is 8
But if for example the byte in binary is 1 1 1 0 * * * * then result is 3.
I would determine how many bit is set contiguous from left to right with one operation.
The results are not necessary numbers from 1-8, just something to distinguish.
I think it's possible in one or two operations, but I don't know how.
If you don't know a solution as short as 2 operations, please write that too, and I won't try it anymore.
Easiest non-branching solution I can think of:
y=~x
y|=y>>4
y|=y>>2
y|=y>>1
Invert x, and extend the lefttmost 1-bit (which corresponds to the leftmost 0-bit in the non-inverted value) to the right. Will give distinct values (not 1-8 though, but it's pretty easy to do a mapping).
110* ****
turns into
001* ****
001* **1*
001* 1*1*
0011 1111
EDIT:
As pointed out in a different answer, using a precomputed lookup table is probably the fastets. Given only 8 bits, it's probably even feasible in terms of memory consumption.
EDIT:
Heh, woops, my bad.. You can skip the invert, and do ands instead.
x&=x>>4
x&=x>>2
x&=x>>1
here
110* ****
gives
110* **0*
110* 0*0*
1100 0000
As you can see all values beginning with 110 will result in the same output (1100 0000).
EDIT:
Actually, the 'and' version is based on undefined behavior (shifting negative numbers), and will usually do the right thing if using signed 8-bit (i.e. char, rather than unsigned char in C), but as I said the behavaior is undefined and might not always work.
I'd second a lookup table... otherwise you can also do something like:
unsigned long inverse_bitscan_reverse(unsigned long value)
{
unsigned long bsr = 0;
_BitScanReverse(&bsr, ~value); // x86 bsr instruction
return bsr;
}
EDIT: Not that you have to be careful of the special case where "value" has no zeroed bits. See the documentation for _BitScanReverse.

generating 'random' number using modulo from a stream of odd numbers

i want to generate a pseudo-random bool stream based on a modulo operation on another stream of integers (say X), so the operation would be
return ( X % 2);
The only problem is that X is a stream of integers that always ends in 1, so for instance would be somehing like 1211, 1221, 1231, 1241 .... is there a way for me to disregard the last bit (without using string manip) so the test doesnt always pass or always fail?
How about (X / 10) % 2 then?
If you'd otherwise be happy to use the last bits, use the penultimate bits instead:
return (x & 0x2) >> 1;
So say the next number from your stream is 23:
1 0 1 1 1 // 23 in binary
& 0 0 0 1 0 // 0x2 in binary
-----------
0 0 0 1 0
Shifting that right by one bit (>> 1) gives 1. With 25, the answer would be 0:
1 1 0 0 1
& 0 0 0 1 0
-----------
0 0 0 0 0
return ( x%20/10 );