Trying to confirm XOR's mathematical property - xor

Is the following property true of the XOR operator ?
A XOR B = C
A XOR C = B
B XOR C = A
What would you call this property ?
This can be tested here. Let me know if there are any cases where this property
doesn't hold true :
int main() {
unsigned a = 128;
unsigned b = 34;
unsigned c = a ^ b;
printf("a ^ c = %u\n", a ^ c); // Gives you b (34)
printf("b ^ c = %u\n", b ^ c); // Gives you a (128)
}

Involution
"The XOR bitwise operation with a given value for one parameter is an involution."

I don't think so, the above can be written as
A XOR A XOR B
Here A XOR A is 0
So the result is 0 XOR C = C

I don't think there is a name for such property. It implies from other properties of the Exclusive Or (see Exclusive Or wiki for more details).
Here is the proof:
If a^b = c, then
a^c = a^(a^b) =
<by associativity>
= (a^a)^b =
= 0^b = b

Related

Why is bitwise OR operation not working as expected when an unsigned char is ORed with 11100000?

I am not able to understand why the operation 'c | 11100000' does not seem to work. But I also noticed that 'c | 10000000' works as expected.
#include <stdio.h>
int main()
{
unsigned char c, c1;
c = c & 0;
c = c | 11100000;
printf("%o \t", c);
/** prints 140 ***/
c = c & 0;
c = c | 111;
c << 5;
printf("%o", c);
/** prints 157 **/
return 0;
}
The constant values that you are using are in decimal format, not binary.
C doesn't support binary constants, but it does support hex constants:
c = c | 0xe0;
...
c = c | 0x7;
Also, this doesn't do anything:
c << 5;
Presumably, you want:
c = c << 5;
The problem of the confusion is that you think that this integer constant 11100000 represents a binary literal. That is 1 and 0 are bit values.
However if you will execute this statement
printf( "11100000 = %x\n", 11100000 );
you will see that the hexadecimal representation of the constant is a95f60
11100000 = a95f60
So in this statement
c = c | 11100000;
the less significant byte that is equal to 0x60 (or in decimal 96) is assigned to the variable c.
It is not the same if to write
c = c | 111;
c <<= 5;
Moreover pay attention to that this expression statement
c << 5;
does not have an effect. It seems you mean
c <<= 5;
that is equivalent to the multiplication of the decimal value 111 by 32 and again assigning the less significant byte to the variable c.
If you will execute this statement
printf( "111 << 5 = %d\n", 111 << 5 );
then you will see that the result is
111 << 5 = 3552
As it is seen 3552 is not the same as 11100000.
So the output of this statement
c = 111 << 5;
printf( "%d\n", c);
is decimal 224.
Opposite to C++ in C there are no integer binary constants.
In C++ there are binary literals and you could obtain the expected result running this program
#include <cstdio.h>
int main()
{
unsigned char c = 0;
c = c | 0b11'100'000;
printf( "%o\t", c );
c = 0b111;
c <<= 5;
printf( "%o\n", c );
}
The program output is
340 340

Is there a way to manipulate the bits that I shift in C

If I have an int a, which is lets say equal to 0.
Is there a way for me to say left shift 101 into the variable and then in another step shift in 011 into it? Then I could get the int decimal number at the end? It would end up becoming 0b00000000000000000000000000101011.Or should I only use the OR operation.
You can't shift bits into the variable; you can OR them in:
int a = 0;
a |= 5;
printf("a = %d\n", a);
a <<= 3;
a |= 3;
printf("a = %d\n", a);
If your system supports binary constants, you can use those instead of decimals (and you can prefix 5 and 3 with 0 for octal or 0x for hexadecimal if you prefer — and you can print with a different format according to taste, too). If the starting value for a isn't known to be 0, you would do a shift-assignment operation before the first |= operation.
Eventually, you have to worry about left-shifting a signed integer value such that overflow occurs — that leads to undefined behaviour. It isn't a problem with the values in the question, though.
You would need to first shift by the required number of bits then perform a bitwise OR of the new data.
int a = 0;
a = a << 3;
a = a | 0x5;
a = a << 3;
a = a | 0x3;
printf("a=%x\n", a);
( Used separate assignments and operators instead of compound operators to make it clearer to beginners. )
Result:
a=2b
Is there a way for me to say left shift 101 into the variable
No. You need to left shift first, then add (or OR) the new value.
int eax = 0;
eax <<= 3;
eax |= 5;
int a = 0;
a << 3;
a |= 0x5;
a << 3;
a |= 0x3;
There isn't a predefined way to "shift in" a value like that. It wouldn't take much time to write a function that could though.
There is - to my knowledge - no operation that "shifts" a number of bits from one integer into another. The left shift operator always fills the arising spaces with 0, such that you have to combine it with, for example, an |-operation (actually a + would have the same effect in your case).
#include <stdio.h>
void printBinary(int b, int nrOfBits) {
for (int mask = (1 << nrOfBits); mask != 0; mask >>=1 ) {
char c = (b & mask) ? '1' : '0';
printf("%c", c);
}
}
int main()
{
int a = 0;
a = (a << 3) | 0x5;
printBinary(a, 8);printf("\n");
a = (a << 3) | 0x3;
printBinary(a, 8);printf("\n");
return 0;
}
When using left shift operators on signed datatypes be careful not to produce undefined behaviour (cf. cppreference concerting arithmetic operations):
When signed integer arithmetic operation overflows (the result does
not fit in the result type), the behavior is undefined

Multiply-subtract in SSE

I am vectorizing a piece of code and at some point I have the following setup:
register m128 a = { 99,99,99,99,99,99,99,99 }
register m128 b = { 100,50,119,30,99,40,50,20 }
I am currently packing shorts in these registers, which is why I have 8 values per register. What I would like to do is subtract the i'th element in b with the corresponding value in a if the i'th value of b is greater than or equal to the value in a (In this case, a is filled with the constant 99 ). To this end, I first use a greater than or equal to operation between b and a, which yields, for this example:
register m128 c = { 1,0,1,0,1,0,0,0 }
To complete the operation, I'd like to use the multiply-and-subtract, i.e. to store in b the operation b -= a*c. The result would then be:
b = { 1,50,20,30,0,40,50,20 }
Is there any operation that does such thing? What I found were fused operations for Haswell, but I am currently working on Sandy-Bridge. Also, if someone has a better idea to do this, please let me know (e.g. I could do a logical subtract: if 1 in c then I subtract, nothing otherwise.
You essentially want an SSE version of this code, right?
if (b >= a)
t = b-a
else
t = b
b = t
Since we want to avoid conditionals for the the SSE version so we can get rid of the control flow like this (note that the mask is inverted):
uint16_t mask = (b>=a)-1
uint16_t tmp = b-a;
uint16_t d = (b & mask) | (tmp & ~mask)
b = d
I've checked the _mm_cmpgt_epi16 intrinsic and it has a nice property in that it returns either 0x0000 for false or 0xFFFF for true, instead of a single bit 0 or 1 (thereby eliminating the need for the first subtraction). Therefore our SSE version might look like this.
__m128i mask = _mm_cmpgt_epi16 (b, a)
__m128i tmp = _mm_sub_epi16 (b, a)
__m128 d = _mm_or_ps (_mm_and_ps (mask, tmp), _mm_andnot_ps (mask, b))
EDIT: harold has mentioned a far less complicated answer. The above solution might be helpful if you need to modify the else part of the if/else.
uint16_t mask = ~( (b>=a)-1 )
uint16_t tmp = a & mask
b = b - tmp
the SSE code will be
__m128i mask = _mm_cmpgt_epi16 (b, a)
__m128i t = _mm_sub_epi16 (b, _mm_and_si128 (mask, a))
Another alternative, if your inputs are unsigned, you can calculate
b = min(b, b-a);
This works, because if a>b then b-a wraps around and is guaranteed to result in a bigger value than b. For a<=b you will always get a value between 0 and b inclusive.
b = _mm_min_epu16(b, _mm_sub_epi16(b,a));
The required _mm_min_epu16 requires SSE4.1 or later (_mm_min_epu8 would require only SSE2).
You can copy b to c, subtract a from c, perform an arithmetic shift right by 15 positions in the 16 bit values, complement the value of c, mask c with a, and finally subtract c from b.
I'm not familiar for the intrinsics syntax, but the steps are:
register m128 c = b;
c -= a;
c >>= 15;
c = ~c;
c &= a;
b -= c;
here is an alternative with fewer steps:
register m128 c = compare_ge(b, a);
c = -c;
c &= a;
b -= c;

Bitwise AND behaves differently than expected?

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int a = 50; // 110010
int b = 30; // 011110
if (a & b) {
printf("Hi");
}
return 0;
}
The code above prints Hi.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int a = 50; // 110010
int b = 13; // 001101
if (a & b) {
printf("Hi");
}
return 0;
}
The code above doesn't print anything.
Logically, you would think that a bitwise AND would mean that all the digits in binary would have to match in order to return true. Instead, in reality, each digit in binary would have to be different for the condition to return false.
I don't understand the point of bitwise AND.
I also understand that false is equivalent to 0 in C.
Like Karthik said it's bitwise.
int a = 50; // 110010 int a = 50; // 110010
int b = 30; // 011110 & int b = 13; // 001101 &
¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯
010010 = 18 000000 = 0 --false
It is a bitwise &. That means the result of the operation is the result of applying & bit by bit on the two operands.
int a = 50; // 110010
int b = 30; // 011110
a & b == 010010 == 18 == true
If you want all the bits to be equal, that's just ==. Or you would bitwise & it with 111111
The operator is bitwise, which means it compares the binary representation of two variables bit by bit. When you have
int a = 50; // 110010
int b = 30; // 011110
int result = a & b; // 010010
What happens is this: the bits of result are set based on the values of the bits in a and b. Each pair of corresponding bits in a and b is compared. Here, since the second and fifth bits (from the right) of both a and b are 1, i.e., true, the comparison of those bits yields true, and correspondingly, the second and fifth bits in result are set to true as well. Consequently, result is nonzero. This nonzero evaluation of a & b would cause "Hi" to print in your first example.
In your second example:
int a = 50; // 110010
int b = 13; // 001101
int result = a & b; // 000000
There is no case in the binary representation of 50 and 13 where corresponding bits are on: the first bit (from the right) is off in 50, on in 13; vice-versa for the second bit, and so on. So the comparison of corresponding bits yields 0 in every case, and no corresponding bit is on in result. Hence result evaluates to zero. This zero result causes "Hi" not to print in your second example.
As to the utility of this operator: bitwise operations are essential in embedded systems programming. They are also extremely efficient for certain problems (e.g. a Sieve of Eratosthenes type program to generate primes). The bitwise or is useful in cryptography. The list goes on...
Case 1:
int a = 50; // 110010
int b = 30; // 011110
if (a & b) =>if (50 & 30) => if( 1 1 0 0 1 0 & => if(010010)=> if(18)=>
0 1 1 1 1 0 )
if(18)=>if(TRUE)=> printf("Hi")
Case 2:
int a = 50; // 110010
int b = 13; // 001101
if (a & b) =>if (50 & 13) => if( 1 1 0 0 1 0 & => if(000000)=> if(0)=>
0 0 1 1 0 1 )
if(0)=>if(FALSE) => NO printf("Hi")
What is not clear to you is that in C, the number 0 is false, and any other number is true.
if (0) {
printf("hi");
}
will do nothing, so if the bit-wise-and operation doesn't produce a single set bit, you have effectively computed an if statement that looks like
if (false) {
printf("hi");
}
As everyone else has done a fine example of showing the bit operation, I'll defer to their math.
This is exactly the purpose of the bitwise and. It's mostly used for bit testing with masks. The net effect is to keep all the common 1s and zero out everything else. Say, for instance you want to test if the 3rd bit is 1, you can just write
if ( a & 4 /*0100*/ )
// do something
As Karthik said there are other methods to compare the operands the way you expected.
"Logically, you would think that a bitwise AND would mean that all the digits in binary would have to match in order to return true. Instead, in reality, each digit in binary would have to be different for the condition to return false."
They don't have to be different. AND would yield zero if both bits were zero, for instance. XOR is the logical operator that returns true only if the bits are different, and XNOR is the one that returns true only if they're the same. Since anything non-zero is true, then to get AND to return true you just need any one bit to be 1 in both of the operands. Conversely, it'll return false if neither of the operands have a 1-bit in common.

what does "|=" operator mean in C?

How does this code work:
int a = 1;
int b = 10;
a |= b;
how the a |= b; works? Seems like |= is not an operator in C?
It works like the | + the = operator, in a similar way as += works.
It is equivalent as
a = a|b;
I suggest you to read this article about operators: http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B#Bitwise_operators
Ans this one about bitwise operation
http://en.wikipedia.org/wiki/Bitwise_operation
Following the pattern of, for example, +=:
a |= b;
// Means the same thing as:
a = a | b;
That is, any bits that are set in either a or b shall be set in a, and those set in neither shall not be set in a.
That's the "bitwise or" equal. It follows in the pattern of the plus equal +=, minus equal -=, etc.
a |= b; is the same as a = a | b;
The expression a |= b; is equivalent to the expression a = a | b;.
This is compound assignment operator.
It has meaning:
a = a | b;
This is the same as
a = a | b;
The same way as += -= etc
Its the bitwise OR operator, and
a |= b;
Its the same thing as
a = a | b;

Resources