Home > Back-end >  Swapping numbers using multiplication method is not working in C
Swapping numbers using multiplication method is not working in C

Time:04-08

Recently I have been coding in C and I was trying to solve a number swapping problem. I have done it the easier way, by using a temporary variable. But my instructor told me use another method without temp variable. This is my code:

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int a,b,temp;
    printf("Enter two numbers: ");
    scanf("%d%d",&a,&b);
    printf("Entered Numbers:%d,%d \n",a,b);
    temp = a;   //This method is the easiest one.
    a = b;
    b = temp;
    printf("Numbers are swapped as: %d,%d \n",a,temp);
    a = (a*b)/a;
    b = (a*b)/b;
    printf("Numbers are swapped as: %d,%d",a,b);
    return EXIT_SUCCESS;
}

I got the output as follows:

Enter two numbers: 50 32
Entered Numbers:50,32 
Numbers swapped with temp are: 32,50 
Numbers swapped without temp are: 50,50

Can anyone guess what might be the error? I believe my math is right, but why is it showing like this?

CodePudding user response:

You have made a silly mistake in your second logic, just replace with mentioned one:

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int a,b,temp;
    printf("Enter two numbers: ");
    scanf("%d%d",&a,&b);
    printf("Entered Numbers:%d,%d \n",a,b);
    temp = a;   //This method is the easiest one.
    a = b;
    b = temp;
    printf("Numbers are swapped as: %d,%d \n",a,temp);
    a = a * b; //Change 1  
    b = a / b; //Change 2 
    a = a / b; //Change 3
    printf("Numbers are swapped as: %d,%d",a,b);
    return EXIT_SUCCESS;
}

CodePudding user response:

You made a mistake in the swapping code: the multiplication method uses 3 steps:

  • compute the product a * b into a
  • divide a by b into b, effectively setting b to the original value of a.
  • divide a by b into a, effectively dividing the product by the original value of a, hence setting a to the original value of b.

The problem with this approach is it does not work for many cases:

  • if b is zero, the first division has undefined behavior, crashing the program in many cases
  • if a is zero, the second division has undefined behavior.
  • if a * b exceeds the range of type int, you also have undefined behavior, producing incorrect results or even a crash (try swapping 65536 and 65536).

There is another method without a temporary variable the is much safer and reliable: instead of multiplying the numbers and dividing the product, you can xor the numbers and use xor again to retrieve the original values and swap them.

Note also that your third printf statement is incorrect: you print the value of temp instead of b.

Here is a modified version:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int a, b, temp;
    printf("Enter two numbers: ");
    if (scanf("%d%d", &a, &b) != 2)
        return EXIT_FAILURE;
    printf("Entered Numbers: %d,%d\n", a, b);
    temp = a;   //This method is the easiest one.
    a = b;
    b = temp;
    printf("Numbers are swapped with temp as: %d,%d\n", a, b);
    a = a ^ b;
    b = a ^ b;
    a = a ^ b;
    printf("Numbers are swapped with xor as: %d,%d\n", a, b);
    a = a * b;
    b = a / b;
    a = a / b;
    printf("Numbers are swapped with multiplication as: %d,%d\n", a, b);
    return EXIT_SUCCESS;
}

Sample runs without optimisations:

Enter two numbers: 12 42
Entered Numbers: 12,42
Numbers are swapped with temp as: 42,12
Numbers are swapped with xor as: 12,42
Numbers are swapped with multiplication as: 42,12
Enter two numbers: 1 0
Entered Numbers: 1,0
Numbers are swapped with temp as: 0,1
Numbers are swapped with xor as: 1,0
Floating point exception: 8
Enter two numbers: 65536 65536
Entered Numbers: 65536,65536
Numbers are swapped with temp as: 65536,65536
Numbers are swapped with xor as: 65536,65536
Floating point exception: 8

The same runs with optimisations (clang or gcc):

Enter two numbers: 12 42
Entered Numbers: 12,42
Numbers are swapped with temp as: 42,12
Numbers are swapped with xor as: 12,42
Numbers are swapped with multiplication as: 42,12
Enter two numbers: 1 0
Entered Numbers: 1,0
Numbers are swapped with temp as: 0,1
Numbers are swapped with xor as: 1,0
Numbers are swapped with multiplication as: 0,1
Enter two numbers: 65536 65536
Entered Numbers: 65536,65536
Numbers are swapped with temp as: 65536,65536
Numbers are swapped with xor as: 65536,65536
Numbers are swapped with multiplication as: 65536,65536

What is going on? Is the compiler broken? As can be verified with Goldbolt's Compiler Explorer, when optimisations are turned on, both clang and gcc are able to identify the 3 swapping methods and generate the same swapping code with 4 mov instructions. Since the third method has undefined behavior on cases where the multiplication or division would fail, producing any result is OK, including the expected one. A blatant case of undefined behavior abuse. Your instructor should be amazed at this discovery.

  • Related