Thread: swaping numbers

  1. #1
    Registered User
    Join Date
    Mar 2004
    Posts
    14

    swaping numbers

    I am trying to put three numbers in order from smallest to largest by swaping them. I can figure out how to get all of them to display after they are swapped. Any help would be great.
    Code:
    void swap2(double a, double b)
    {	
    	double temp = a;
    	a = b;
    	b = temp;
    }
    
    int main()
    {
    	double a, b, c;	
    	cout<<"Enter three numbers.";						
    	cout<<endl;				
    	cin>>a >>b >>c;				
    	cout<<endl;			
    		
    	if (a < b && a < c)					
    	{
    			
             	cout<<a;	 
    	cout<<endl;							
    	}
    
    	else if (b < c)
    	{
    		cout<<b;
    		cout<<endl;
    	}
    	
    	else 
    	{
    		swap2(b,c);
    		cout<<c
    		cout<<endl;
    		cout<<b;
    		cout<<endl;
    	}
    
    return 0;
    }
    Last edited by bj31t; 03-29-2004 at 04:46 PM. Reason: code tags

  2. #2
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    To start with, this won't work too well:
    >>void swap2(double a, double b)
    You need to pass the address of the variable in order to perform the swap. All you're currrently doing is swapping the values around in local variables, leaving those in main() as they were.

    Code:
    void swap2(double *a, double *b)
    {
      double  temp = *a;
      *a = *b;
      *b = temp;
    }
    
    swap2(&b, &c);
    You'll also need to store your input in an array if you want to make things more efficient.

    Try looking up the bubble sort on google
    http://www.google.com/search?q=bubble+sort
    It's pretty inefficient, but it's a good sorting routine to learn as a beginner.

    When your ready, take a look at Prelude's Corner for more detailed stuff
    http://faq.cprogramming.com/cgi-bin/...&id=1073086407
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  3. #3
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    References would be better.
    Code:
    void swap3(double& a, double& b)
    {
      double  temp = a;
      a = b;
      b = temp;
    }
    
    swap3(b, c);
    My best code is written with the delete key.

  4. #4
    Registered User
    Join Date
    Mar 2004
    Posts
    14
    Prelude, could you explain what you mean. I dont understand.
    Thanks

  5. #5
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >Prelude, could you explain what you mean.
    A reference is a (potentially) different name for the same object. Instead of passing a pointer to the address of the object as Hammer showed you, passing a reference gives you simpler syntax. You pass b and c without having to worry about passing an address, then swap a and b without having to worry about dereferencing.

    A good C++ book will give you more detail than I can in a short post.
    My best code is written with the delete key.

  6. #6
    carry on JaWiB's Avatar
    Join Date
    Feb 2003
    Location
    Seattle, WA
    Posts
    1,972
    Just wondering...
    Code:
    template <typename T>
    void swap (T& a, T& b)
    {
    a^=b^=a^=b;
    }
    Is there any disadvantage to that? (Or is there any real advantage to it?)
    "Think not but that I know these things; or think
    I know them not: not therefore am I short
    Of knowing what I ought."
    -John Milton, Paradise Regained (1671)

    "Work hard and it might happen."
    -XSquared

  7. #7
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Disadvantages:
    - only works on integral types of T
    - will most likely confuse the average reader of the code
    - there's no real speed gain on modern CPU's

    Advantages:
    - cool to look at
    - will most likely confuse the average reader of the code

    gg

  8. #8
    carry on JaWiB's Avatar
    Join Date
    Feb 2003
    Location
    Seattle, WA
    Posts
    1,972
    Quote Originally Posted by Codeplug
    Disadvantages:
    ...
    - will most likely confuse the average reader of the code
    ...

    Advantages:
    ...
    - will most likely confuse the average reader of the code

    gg
    Rofl .
    "Think not but that I know these things; or think
    I know them not: not therefore am I short
    Of knowing what I ought."
    -John Milton, Paradise Regained (1671)

    "Work hard and it might happen."
    -XSquared

  9. #9
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >Is there any disadvantage to that?
    The most obvious (or maybe not judging from how often I see the construct) is that it modifies an object more than once between sequence points and is thus undefined. Assuming it works correctly then if a and b both refer to the same variable unexpected things will happen if you aren't prepared for them.
    My best code is written with the delete key.

  10. #10
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    >> it modifies an object more than once between sequence points and is thus undefined

    I'm gonna argue
    From ISO/IEC FDIS 14882 (Final Draft)
    1.9-7 Accessing an object designated by a volatile lvalue (basic.lval), modifying an object, calling a library I/O function, or calling a function that does any of those operations are all side effects, which are changes in the state of the execution environment. Evaluation of an expression might produce side effects. At certain specified points in the execution sequence called sequence points, all side effects of previous evaluations shall be complete and no side effects of subsequent evaluations shall have taken place.
    Even though there are multiple assignments within a single sequence point, I would argue that the statement is still well defined due to the left to right associativity of the xor-equals operator.

    From ISO/IEC FDIS 14882 (Final Draft)
    1.9-15 [Note: operators can be regrouped according to the usual mathematical rules only where the operators really are associative or commutative.*
    [Footnote: Overloaded operators are never assumed to be associative or commutative. --- end foonote]
    For example, in the following fragment
    int a, b;
    /*...*/
    a = a + 32760 + b + 5;
    the expression statement behaves exactly the same as
    a = (((a + 32760) + b) + 5);
    due to the associativity and precedence of these operators. Thus, the result of the sum (a + 32760) is next added to b, and that result is then added to 5 which results in the value assigned to a. On a machine in which overflows produce an exception and in which the range of values representable by an int is [-32768,+32767], the implementation cannot rewrite this expression as
    a = ((a + b) + 32765);
    since if the values for a and b were, respectively, -32754 and -15, the sum a + b would produce an exception while the original expression would not; nor can the expression be rewritten either as
    a = ((a + 32765) + b);
    or
    a = (a + (b + 32765));
    since the values for a and b might have been, respectively, 4 and -8 or -17 and 12. However on a machine in which overflows do not produce an exception and in which the results of overflows are reversible, the above expression statement can be rewritten by the implementation in any of the above ways because the same result will occur. ]
    As section 1.9-15 describes, compilers are only allowed to regroup mathematically associative or commutative operators of equal precedence if doing so gives the same results as not regrouping the operators.

    So my assertion is that the "^=" operator is not associative or commutative, so the compiler must adhere to the left-to-right associativity of the xor-equals operator. And thus, is equivalent to the following:
    Code:
    a ^= b;
    b ^= a;
    a ^= b;
    [atleast that's my humble interpretation of things]

    gg

  11. #11
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    hmm... but speedwise shouldnt assignment be faster than mathematical calculations, even if it is 3 simple XORs?

    though it doesnt really matter, I suppose
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  12. #12
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Hmmmm, lets see
    Code:
    void s1(int &a, int &b)
    {
        a ^= b ^= a ^= b;
    }
    
    void s2(int &a, int &b)
    {
        int t = a;
        a = b;
        b = t;
    }
    Code:
    PUBLIC  ?s1@@YAXAAH0@Z                  ; s1
    _TEXT   SEGMENT
    _a$ = 8
    _b$ = 12
    ?s1@@YAXAAH0@Z PROC NEAR                ; s1, COMDAT
    
    ; 13   :     a ^= b ^= a ^= b;
    
        mov ecx, DWORD PTR _b$[esp-4]
        mov eax, DWORD PTR _a$[esp-4]
        push    esi
        mov edx, DWORD PTR [ecx]
        mov esi, DWORD PTR [eax]
        xor esi, edx
        mov DWORD PTR [eax], esi
        mov edx, esi
        mov esi, DWORD PTR [ecx]
        xor esi, edx
        mov DWORD PTR [ecx], esi
        mov edx, DWORD PTR [eax]
        mov ecx, esi
        pop esi
        xor edx, ecx
        mov DWORD PTR [eax], edx
    
    ; 14   : }
    
        ret 0
    ?s1@@YAXAAH0@Z ENDP                 ; s1
    
    
    PUBLIC  ?s2@@YAXAAH0@Z                  ; s2
    _TEXT   SEGMENT
    _a$ = 8
    _b$ = 12
    ?s2@@YAXAAH0@Z PROC NEAR                ; s2, COMDAT
    
    ; 18   :     int t = a;
    ; 19   :     a = b;
    
        mov edx, DWORD PTR _b$[esp-4]
        mov eax, DWORD PTR _a$[esp-4]
        push    esi
        mov esi, DWORD PTR [edx]
        mov ecx, DWORD PTR [eax]
        mov DWORD PTR [eax], esi
    
    ; 20   :     b = t;
    
        mov DWORD PTR [edx], ecx
        pop esi
    
    ; 21   : }
    
        ret 0
    ?s2@@YAXAAH0@Z ENDP                 ; s2
    Looks like your right.....for this x86 assembly anyways.
    Maybe Bubba can do some by-hand sloptamizations for us

    gg

  13. #13
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >I would argue that the statement is still well defined due to the left to right associativity
    Section 5, paragraph 4 of the draft standard:
    Code:
    Except where noted, the order of evaluation of operands of individual operators and subexpressions of individual
    expressions, and the order in which side effects take place, is unspecified. Between the previous and
    next sequence point a scalar 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. The
    requirements of this paragraph shall be met for each allowable ordering of the subexpressions of a full
    expression; otherwise the behavior is undefined. [Example:
            i = v[i++]; // the behavior is undefined
            i = 7, i++, i++; // ‘i’ becomes 9
            i = ++i + 1; // the behavior is undefined
            i = i + 1; // the value of ’i’ is incremented
    —end example]
    Look up the definition of a sequence point and then tell me if ^= is one of them.
    My best code is written with the delete key.

  14. #14
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Well, can't argue with that

    >> i = v[i++]; // the behavior is undefined

    Never looked a sequence points as encompassing both the rvalue's and lvalue's......interesting.
    Although 99.9% of the time (if not 100%), compilers will implement the expected behavior......which of course, isn't an excuse for writting such code

    gg

  15. #15
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >Although 99.9% of the time (if not 100%), compilers will implement the expected behavior
    This is true.

    >which of course, isn't an excuse for writting such code
    This is also true. But the issue of only being able to swap integral values and swapping a variable with itself (a very possible occurance) using an xor swap persist whether the swap is written correctly, or the compiler "does the right thing". There are too many silent restrictions with that construct for me to be entirely comfortable with it. Couple that with the obscure nature of xoring two values to implement a swap without a temporary and you have a nasty bug waiting to happen.
    My best code is written with the delete key.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Question about random numbers
    By Kempelen in forum C Programming
    Replies: 2
    Last Post: 07-02-2008, 06:28 AM
  2. Comparing numbers to a list of numbers held in a text file
    By jmajeremy in forum C++ Programming
    Replies: 3
    Last Post: 11-06-2006, 07:56 AM
  3. Logical errors with seach function
    By Taka in forum C Programming
    Replies: 4
    Last Post: 09-18-2006, 05:20 AM
  4. the definition of a mathematical "average" or "mean"
    By DavidP in forum A Brief History of Cprogramming.com
    Replies: 7
    Last Post: 12-03-2002, 11:15 AM
  5. A (complex) question on numbers
    By Unregistered in forum C++ Programming
    Replies: 8
    Last Post: 02-03-2002, 06:38 PM