Thread: a short question

  1. #1
    Registered User
    Join Date
    Oct 2005
    Posts
    16

    a short question

    Hi!

    How dose this code work?
    what dose it mean?
    /* C trick to swap n1 and n2 */

    n1^=n2^=n1^=n2;

  2. #2
    Sr. Software Engineer filker0's Avatar
    Join Date
    Sep 2005
    Location
    West Virginia
    Posts
    235
    Is this a homework assignment?

    I'll give you a hint. Assuming n1 and n2 to be integral types (char, int, long, unsigned), you're doing exclusive OR operations. Work it out on paper with ones and zeros. Remember that evaluation is grouped from right to left.

  3. #3
    aoeuhtns
    Join Date
    Jul 2005
    Posts
    581
    Rewriting this into separate lines, we get:

    n1 ^= n2;
    n2 ^= n1;
    n1 ^= n2;

    Rewriting again,

    n1 = n1 ^ n2;
    n2 = n2 ^ n1;
    n1 = n1 ^ n2;

    One property of the bitwise xor operator is that (A ^ B) ^ A = B. And remember, it is commutative, i.e. A ^ B = B ^ A.

    Let n1 = A and let n2 = B. Then we get

    n1 = n1 ^ n2; /* Assigns A ^ B to n1. n2 still equals B. */
    n2 = n2 ^ n1; /* Assigns B ^ (A ^ B) to n2. So n2 equals A, n1 equals (A ^ B) */
    n1 = n1 ^ n2; /* Assigns (A ^ B) ^ A to n1. So n1 equals B. */

    The end result is that n1 and n2 have been xor'ed through each other.


    Note that this only works if n1 and n2 are distinct numbers. I.e. *p ^= *q ^= *p ^= *q fails miserably if p and q are pointing at the same number. It's generally better to use a third-party, temporary variable. Using a third-party variable works for 'all' datatypes (I'm talking about C++ here), it makes your code more readable, and it makes your code more generalized, instead of relying on the particular behaviors of integers.

    Compilers with optimisations turned on can recognize both forms of swapping, so one is not necessarily faster than the other.

  4. #4
    Registered User
    Join Date
    Mar 2005
    Location
    Saudi Arabia
    Posts
    4

    I hope this helps

    the ^ operator xors the bits:

    1^0 = 1
    0^1 = 1
    0 otherwise

    This statment can be exapnded as follows (from right to left) :

    n1 = n1 ^ n2;
    n2 = n2 ^ n1;
    n1 = n1 ^ n2;

    For Example if n1 = 30 = 0001 1110 and n2 = 21 = 0001 0101
    then:
    n1 = n1 ^ n2 = 0000 1011
    n2 = n2 ^ n1 = 0001 1110
    n1 = n1 ^ n2 = 0001 0101

    n1 = 21; n2 = 30

  5. #5
    Registered User
    Join Date
    Oct 2005
    Posts
    16
    No, is not a homework assignment.
    I try to understand this program.

    Code:
    #include <stdio.h>      
    /* Function f(n) returns the n'th Fibonacci number
     * It uses ALGORITHM 2C: NON-RECURSIVE LOOP
     */
    unsigned int f(int n) {
        int i;
        unsigned int n1=1,n2=1;
    
        for(i=1; i<=n; i++) {
            n1+=n2;
            n1^=n2^=n1^=n2; /* C trick to swap n1 and n2 */
          printf("%d",n1);
        }
        return n1;
    }
    /* Function f_print(n) prints the n'th Fibonacci number */
    void f_print(int n) {
        printf("%dth Fibonacci number is %lu\n",n,f(n));
    }
    /* Function main() is the program entry point in C */
    int main(void) {
        f_print(20);
        return 0;
    }

  6. #6
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  7. #7
    Registered Luser cwr's Avatar
    Join Date
    Jul 2005
    Location
    Sydney, Australia
    Posts
    869
    Quote Originally Posted by Dave_Sinkula
    That thread doesn't show the example where the xor's are chained together in a single expression. I should also point out that a ^= b ^= a ^=b is undefined due to multiple side effects:

    "Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored."

  8. #8
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Dang. I was really hoping for folks to hit on this:
    Quote Originally Posted by Salem
    > and doesn't use an temporary variable (thus faster):
    I very much doubt it.
    Every time I've tried these "cute" methods, all they do is confuse the compiler optimiser (as well as the average reader).

    [...]

    Stick to using a temporary - it always works, it works with any type and the compiler optimiser will see what you are doing. With any luck, it will rearrange the following code to effectively eliminate the swap from ever happening.
    For those who missed it, repeat after me: "we're not in the 70's, we're not in the 70's, ..."

    'Cuz even if you "correct" it, it still sucks.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    *puts down flame thrower for another thread*
    Not to mention http://www.eskimo.com/~scs/C-faq/q10.3.html
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. int and unsignd short
    By a0161 in forum C Programming
    Replies: 2
    Last Post: 11-11-2008, 04:14 AM
  2. Exam Question - Possible Mistake?
    By Richie T in forum C++ Programming
    Replies: 15
    Last Post: 05-08-2006, 03:44 PM
  3. Simple Short Class Question
    By Travis Dane in forum C++ Programming
    Replies: 2
    Last Post: 12-24-2002, 07:12 PM
  4. traversal of tree (short question)
    By mackol in forum C Programming
    Replies: 5
    Last Post: 11-25-2002, 08:41 AM
  5. Replies: 1
    Last Post: 01-23-2002, 03:34 AM