Wapitix
Wapitix

Reputation: 53

XOR operation in C

I've been facing a problem for a few hours with my XOR operation in C.

I'm trying to XOR the content of two char * between each other.

char* toto = malloc(sizeof(char)*5);
char* bob = malloc(sizeof(char)*5);

They both contain only 0 and 1 with 5 slots each.

The printf for toto returns 00011 and bob returns 11111.

printf("%s", toto) => 11111
printf("%s", bob)  => 00011

These are the two values that I'm trying to XOR in the end.

First I proceed by steps :

1- Translate each of them into an int value

int val_toto = atoi(toto); 
int val_bob = atoi(bob);

// printf("%d", val_toto) => 11111
// printf("%d", val_bob)  => 11

As you can see the 0 in bob disapeared, no problem.

2- Use the XOR operator ^ between their respective same bits

int result = val_toto ^ val_bob;

And here comes the problem :

printf("%d", result) => 11116

The result of the XOR operation should be

  11111
^ 00011  // the 0 are taken care of even if not showed in printf
-------
  11100  // but I get 1116 ???

The real deal is that the problem occurs only when I use that combination for toto and bob. The XOR operations works fine for all of them, example :

toto => 00101   // as char*
bob => 000001
//then I use atoi() with each of them
toto => 101     // as int
bob => 1  

And as a result I get what's expect :

101 XOR 1 => 100 //as int

Do you have any idea why it works fine in the combination above for instance but never when I have a 11111 ?

Thank you

Upvotes: 1

Views: 918

Answers (3)

anastaciu
anastaciu

Reputation: 23802

The problem was already pointed out in the comments and in David Grayson answer.

For a solution, unless you absolutely need to, you wouldn't need to convert to int at all, you can perform the XOR in each individual character and save the result in a new char array, something like this:

char toto[] = "11111";
char bobo[] = "00011";

size_t len = strlen(toto);  // use strlen only if toto is null terminated
                            // otherwise use the size of the array
char result[len]; 
                           
for(size_t i = 0; i < len; i++) // same here
{
    result[i] = (toto[i] ^ bobo[i]) + '0';
}

printf("%s", result); // again if the arrays are null terminated,
                      // otherwise print it in a for cycle
                      // using the array size

Output:

11100

If need be you can always safely convert the final value by using strtol:

char *end;
printf("%ld", strtol(result, &end, 2));

Output:

28

Pending error checks on end and errno.

Live sample

Upvotes: 1

fares
fares

Reputation: 93

when you execute int result = val_toto ^ val_bob;, you are using the xor operator with two decimal, not binary numbers. 00011 becomes not 3 but rather 11 in decimal. to correct this mistake, try my code:

char *str="1100"; // in binary now convert it to decimal so it became 12 
char *endptr=NULL; // to detect any mistake 
int num = strtol(str, &endptr, 2); // strtol meams str to long 2 (binary base ) 
if (endptr!=NULL) { printf("error\n"); exit(1); }
printf("%d\n", num); // will print 12. now you can use it with xor 

Upvotes: 1

David Grayson
David Grayson

Reputation: 87406

Both atoi and the %d specifier for printf assume you are dealing with decimal-formatted numbers, not binary. When you did your XOR calculation, you assumed that 11111 and 00011 were binary.

Upvotes: 2

Related Questions