Re: swapping two numbers

2006-06-25 Thread Yitzchak Scott-Thoennes
On Sun, Jun 25, 2006 at 12:31:19AM -0700, Larry Rosler wrote:
  From: Philippe BooK Bruhat
  Sent: Saturday, June 24, 2006 04:10
  To: fwp@perl.org
  Subject: Re: swapping two numbers
 
 
  Le vendredi 23 juin 2006 ? 17:40, Samy Kamkar ?crivait:
   Although x could overflow in this case, where it wouldn't with an xor,
   right?
 
  I've quickly tried to overflow it, but I didn't manage to break it.
  It looks like even if you overflow x with the first addition, you
  cross the border in the other direction when doing the substraction.
 
  --
   Philippe BooK Bruhat
 
 The issue has nothing to do with overflow; everything to do with loss of
 precision.  Subtraction of two nearly equal numbers, or addition of two
 numbers of opposite sign and nearly equal magnitude) followed by a second
 similar computation can produce results with few or no significant bits.
 
 The only correct way to perform these in-place swap operations is to treat
 the operands as bit patterns and use the xor operation.

I disagree.

If we are talking about non-integers (or integers whose magnitude
exceeds the available precision), xor isn't even a possibility in pure
perl; +/- is the only possiblity, with the loss-of-precision you
mention restricting which values it will perfectly work for.

But if we are talking about integers, so long as the intermediate
values stay in a fully representable range (usually 53 bits) there's
no problem with the +/- approach; the xor approach, on the other hand,
will only work correctly with operands representable as unsigned ints
of the size chosen by perl's configure (under no integer) or signed
ints (under use integer).

Either way, xor is the loser.


Re: swapping two numbers

2006-06-24 Thread Samy Kamkar
Although x could overflow in this case, where it wouldn't with an xor, 
right?


Leonid Grinberg wrote:

not in-place cause it's 3 lines, but does not use an external temporay
value, and should be language-independent:
  x = x + y
  y = x - y
  x = x - y
(IIRC my high school BASIC teacher taught us that)


Yeah, that works. Who said that it can't be 3 lines.




Re: swapping two numbers

2006-06-24 Thread Chris Dolan

On Jun 23, 2006, at 5:01 PM, David Westbrook wrote:


Michael R. Wolf wrote:

not in-place cause it's 3 lines, but does not use an external  
temporay value, and should be language-independent:

 x = x + y
 y = x - y
 x = x - y
(IIRC my high school BASIC teacher taught us that)


This works:
  $a -= $b = ($a += $b) - $b;

Chris
--
Chris Dolan, Software Developer, http://www.chrisdolan.net/
Public key: http://www.chrisdolan.net/public.key
vCard: http://www.chrisdolan.net/ChrisDolan.vcf





Re: swapping two numbers

2006-06-24 Thread Philippe BooK Bruhat
Le vendredi 23 juin 2006 à 17:40, Samy Kamkar écrivait:
 Although x could overflow in this case, where it wouldn't with an xor, 
 right?

I've quickly tried to overflow it, but I didn't manage to break it.
It looks like even if you overflow x with the first addition, you
cross the border in the other direction when doing the substraction.

-- 
 Philippe BooK Bruhat

 The only way to get a better government is to get better voters.
   (Moral from Groo The Wanderer #109 (Epic))


RE: SPUG: swapping two numbers

2006-06-23 Thread DeRykus, Charles E


M I was digging through some old code and came across a proof that I
had done 
M that you can swap two numbers in place (i.e. without using an
external 
M temporary value).

M Of course, in Perl, we can just do this:
M  ($x, $y) = ($y, $x)

M But I was challenged (at a GSLUG meeting) to do it in a
language-independent way.  
M Since the guy mentioned he had known the solution for 20+ years, I
descended into 
M bit-flipping land and came up with a solution.

M (BTW:  I'm not sure why my first gut reaction was right.  I guess
I've been in the 
M business long enough.  There's no way my conscious mind came up with
this solution!!!  
M Nevertheless, my subconscious came up with this solution within about
3 seconds.  
M Brains are amazing!!!)

M I present it here as an interesting piece of code:

M #! /usr/bin/perl -w

M use warnings;
M use strict;

M my $iterations = shift @ARGV || 10;

M for (my $i = 0; $i  $iterations; $i++) {
M   my ($orig_a, $a) = (int(rand 1000)) x 2;
M   my ($orig_b, $b) = (int(rand 1000)) x 2;

M   # Original solution:
M   #$a = $a ^ $b;
M   #$b = $b ^ $a;
M   #$a = $a ^ $b;
M   # Refined to use op=
M   #$a ^= $b;
M   #$b ^= $a;
M   #$a ^= $b;

M   # Utilizing op= value, factored onto one line
M   #$a ^= ($b ^= ($a ^= $b));
M   # Refined to remove unnecessary parens
M$a ^= $b ^= $a ^= $b;

'Algorithms with Perl' has your original, refined solution in the
Crytography chapter (pg. 539 'Swapping values with XOR') but not
the nice, de-cluttering refinement.


-- 
Charles DeRykus