[net.lang.c] <=> and obfuscation

jss@sjuvax.UUCP (J. Shapiro) (02/06/85)

[Aren't you hungry...]

	To exchange two items without an intermediate variable, try:

	b ^= a ^= b ^= a

Jon Shapiro

arnold@gatech.UUCP (Arnold Robbins) (02/07/85)

> [Aren't you hungry...]
> 
> 	To exchange two items without an intermediate variable, try:
> 
> 	b ^= a ^= b ^= a
> 
> Jon Shapiro

However, if a == b when you start out, you end up with a == 0 && b == 0.

This also only works on integer style variables.
-- 
Arnold Robbins
CSNET:	arnold@gatech	ARPA:	arnold%gatech.csnet@csnet-relay.arpa
UUCP:	{ akgua, allegra, hplabs, ihnp4, seismo, ut-sally }!gatech!arnold

Help advance the state of Computer Science: Nuke a PR1ME today!

ndiamond@watdaisy.UUCP (Norman Diamond) (02/08/85)

> 	To exchange two items without an intermediate variable, try:
> 
> 	b ^= a ^= b ^= a
> 
> Jon Shapiro

Try it enough, and you'll see that some compilers bind the value of the
first b before it is assigned at its second appearance, and other compilers
bind it afterwards.  Correct results are obtained in the latter case.
Correct programming is obtained in neither case.
-- 

   Norman Diamond

UUCP:  {decvax|utzoo|ihnp4|allegra|clyde}!watmath!watdaisy!ndiamond
CSNET: ndiamond%watdaisy@waterloo.csnet
ARPA:  ndiamond%watdaisy%waterloo.csnet@csnet-relay.arpa

"Opinions are those of the keyboard, and do not reflect on me or higher-ups."

guy@rlgvax.UUCP (Guy Harris) (02/08/85)

> > 	To exchange two items without an intermediate variable, try:
> > 
> > 	b ^= a ^= b ^= a
> > 
> 
> However, if a == b when you start out, you end up with a == 0 && b == 0.

How so?  XOR preserves information; i.e., for any two Boolean values "a" and "b"
if you know "a" and "a XOR b" you can always determine "b".  Thus, none of
the three XOR steps lose any information.  (Try doing it with all four possible
combinations of Boolean values of "a" and "b".)

Of course, none of this changes the fact that 1) as you mention, it only works
if the language permits you to XOR the values, 2) it's obscure, and 3) in at
least 90% of the cases you can do it faster by just moving things around.

	Guy Harris
	{seismo,ihnp4,allegra}!rlgvax!guy

hammond@petrus.UUCP (02/08/85)

> > 	To exchange two items without an intermediate variable, try:
> > 
> > 	b ^= a ^= b ^= a
> 
> However, if a == b when you start out, you end up with a == 0 && b == 0.
> 
NO!, I just tried it on our compiler, if a!=0 && b!=0 && a==b then
after the suggested line the variables still have the same value.
>
> This also only works on integer style variables.

Good point.

gupta@asgb.UUCP (Yogesh K Gupta) (02/11/85)

> > 	To exchange two items without an intermediate variable, try:
> > 
> > 	b ^= a ^= b ^= a
>
>  This works for integer variables only.

In C, the ^ is a bitwise operator. Thus,
	b ^= a ^= b ^= a
will exchange the bit patterns in the two variables.
As long as the two variables are of the SAME type, the values will be
swapped.

As to the efficiency and programming style ...

-- 
Yogesh Gupta                           Advanced Systems Group,
{sdcrdcf, sdcsvax}!bmcg!asgb!gupta     Burroughs Corp., Boulder, CO.
--------------------------------------------------------------------
	All opinions contained in this message are my own and do not
	reflect those of my employer or the plant on my desk.

gino@voder.UUCP (Gino Bloch) (02/12/85)

> > [Aren't you hungry...]

> > 	To exchange two items without an intermediate variable, try:
> > 	b ^= a ^= b ^= a

> However, if a == b when you start out, you end up with a == 0 && b == 0.
Not according to my truth table
-- 
Gene E. Bloch (...!nsc!voder!gino)
The opinions expressed above are accidents.

jss@sjuvax.UUCP (J. Shapiro) (02/12/85)

[Aren't you hungry...]

b ^= a ^= b ^= a

> However, if a == b when you start out, you end up with a == 0 && b == 0.
>
> Arnold Robbins...

will work even if A = B. Suppose a = b = 1011 0100.

a = 1011 0100
b ^= a = 0000 0000
now b is 0000 0000
a ^= b ^= a = XOR of 1011 0100 and 0000 0000 == 1011 0100
now b is 0000 0000, and a is 1011 0100
b ^= a ^= b ^= a == 0000 0000 ^= 1011 0100 = 1011 0100

I believe that this works on *any* lvalues. If it doesn't work on your
system, make sure it isn't the system at fault.  I could see it not working
for arrays of different sizes.

	"There are a number of assignment operators... All require an lvalue as
their left operand." K&R p 191.

	And if you don't believe me, go read Rob Pike's paper on Multiwindow
bitmapped graphics.  It is how he says the bitmap swap should be
implemented, and I have *seen* it work with my own eyes.

Jon Shapiro
Haverford College

stewart@houxf.UUCP (Bill Stewart HO 4K-435 x0705) (02/13/85)

People have been arguing about the statement that
	b ^= a ^= b ^= a;
gives 0 when a and b are the same.  However, you've misunderstood the original
statement - the problem is not when a and b have the same VALUE, but when they
have the same ADDRESS.  Yes, it works fine when a and b are different variables
with the same value.  However, in a subroutine you might get two variables with
the same address.  Then the statement is equivalent to

	a ^= a ^= a ^= a

Well, a^=a becomes zero, gets ^ed with a, which is now 0m and gets ^ed with 0
again, still giving 0.
-- 
Bill Stewart	ho95c!wcs AT&T Bell Labs, Holmdel NJ
HO 4K-435 x0705   (201-949-0705)
{allegra, ucbvax!ihnp4, decvax!harpo}!houxf!stewart
------
Sorry if the articles I'm replying to re ancient; we lost news for a month.

jss@sjuvax.UUCP (J. Shapiro) (02/16/85)

[Aren't you hungry..?]

> People have been arguing about the statement that
> 	b ^= a ^= b ^= a;
> gives 0 when a and b are the same.  However, you've misunderstood the
> original statement - the problem is not when a and b have the same VALUE, 
> but when they have the same ADDRESS. 
> -- 
> Bill Stewart	ho95c!wcs AT&T Bell Labs, Holmdel NJ
> HO 4K-435 x0705   (201-949-0705)
> {allegra, ucbvax!ihnp4, decvax!harpo}!houxf!stewart

I might suggest that if you are foolish enough to try to swap a and b where
&a == &b, you deserve what you get... There *is* a certain poetic justice 
to it. ;-)


Jon Shapiro
Haverford College