AaronParkes
AaronParkes

Reputation: 311

Exchanging one bit with another in a integer, code does not work

Write a program that exchanges the values of the bits on positions 3, 4 and 5 with bits on positions 24, 25 and 26 of a given 32-bit unsigned integer.

So above is the exercise and below are my workings.

int number = 28;                                //number                         -0001 1100    28
int bit3 = (number >> 3) & 1;                   //obtain bit 3rd bit from left   -0000 0001     1
int bit3return = bit3 << 3;                     //return bit to possition        -0000 1000     8
int numberReturn = number & (~(bit3return));    //number with bit place reversed -0001 0100    20

int number2 = 20;                               //number                         -0001 0100    20
int bit3Return = 1 << 3;                        //return bit to possition        -0000 1000     8
int numberReturn2 = number2 + bit3Return;       //number with bit place reversed -0001 0100    28

Here is my final code.

Console.WriteLine("Enter a number to be modified:");
int num = int.Parse(Console.ReadLine());

int b3 = (num >> 3) & 1;
int b4 = (num >> 4) & 1;
int b5 = (num >> 5) & 1;
int b24 = (num >> 24) & 1;
int b25 = (num >> 25) & 1;
int b26 = (num >> 26) & 1;

num = num & (~(1 << b24)) | (b3 << 24);
num = num & (~(1 << b3)) | (b24 << 3);
num = num & (~(1 << b25)) | (b4 << 25);
num = num & (~(1 << b4)) | (b25 << 4);
num = num & (~(1 << b26)) | (b5 << 26);
num = num & (~(1 << b5)) | (b26 << 5);

Console.WriteLine(num);

Problem is, it does not work:

I input 56 which is:

Output should be 117440512 which is:

However I get 117440568 which is:

If I input 117440512 I get the same output, so 0 becomes 1 but 1 does not become 0. Please help.

Upvotes: 1

Views: 228

Answers (3)

Andrew Brown
Andrew Brown

Reputation: 167

For example with input x

x = 1234567890              // == 0100 1001 1001 0110 0000 0010 1101 0010

Get upper and lower mask

umask = 7 << 24             // == 0000 0111 0000 0000 0000 0000 0000 0000
lmask = 7 << 3              // == 0000 0000 0000 0000 0000 0000 0011 1000

Get the bits that we want to swap

y = x & umask               // == 0000 0001 0000 0000 0000 0000 0000 0000
z = x & lmask               // == 0000 0000 0000 0000 0000 0000 0001 0000

Shift y to the lower position

y = y >> (24 - 3)           // == 0000 0000 0000 0000 0000 0000 0000 1000

Shift z to the higher position

z = z << (24 - 3)           // == 0000 0010 0000 0000 0000 0000 0000 0000

Mask out old values

x = x & ~( umask | lmask )  // == 0100 1000 1001 0110 0000 0010 1100 0010

Put in new values

x = x | y | z               // == 0100 1010 1001 0110 0000 0010 1100 1010

Upvotes: 1

Damien_The_Unbeliever
Damien_The_Unbeliever

Reputation: 239664

Given:

int b24 = (num >> 24) & 1;

Means that b24 can only contain 0 or 1. Which means:

num & (~(1 << b24))

Will be clearing bit 0 or 1 of num. And then:

| (b3 << 24);

is either setting bit 24 (if b3 is 1) or is leaving it at whatever value it currently has (if b3 is 0). You probably wanted:

num & (~(1 << 24))

to clear bit 24 of the number.

(Apply same logic for all of the remaining lines. Each one repeatedly clears either bit 0 or 1 of num and then attempts to set a different bit's value)

Upvotes: 1

Ondrej Tucny
Ondrej Tucny

Reputation: 27962

Your code is unnecessarily complicated. Think of manipulating with all three bits at the same time. The algorithm should be as follows:

  1. Separate bits 3, 4, 5 by masking with … 0011 1000;
  2. Shift left by 21 to positions 24, 25, 26;
  3. Separate bits 24, 25, 26 by masking with … 0111 0000 …;
  4. Shift right by 21 to positions 3, 4, 5;
  5. Mask-out 3, 4, 5, 24, 25, 26 in the original variable by ANDing with '…1000 1111 … 1100 01111';
  6. Mix-in the temporary results of (2) and (4) by ORing them to the results of (5).

Actual code implementation is left upon the reader.

Upvotes: 2

Related Questions