Bitwise Xor optimizing and/or/not use

I was looking at the code for two different MD5 implementations and I seen F (a bitwise ternary operation) implemented two different ways:

in C:

#define f1(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define f2(x, y, z) ((z) ^ ((x) & ((z) ^ (y))))

In Pseudo:

f1 = (x And y) Or ((Not x) And z)
f2 = z Xor (x And (z Xor y))

What I can't wrap my brain around is how someone came up with f2 in the first place. I could have come up with f1 on my own because its the logical code to write when you hear (if x then y else z) - but I couldn't have come up with f2.

To be clear - I understand what f2 is doing and how Xor works - I just can't understand how someone can go from f1 to f2 .. how did they know using xor in that way was equivalent?

I can't just use something because it works - I want to understand why it works.

Can someone "explain the math", so to speak?
Are there specific rules where you can use Xor to optimize And/Or/Not?

链接地址: http://www.djcxy.com/p/58202.html

上一篇: 按位交换,无XOR

下一篇: 按位异或优化和/或/不使用