Bit Manipulation to store multiple values in one int C++

bit-manipulation, c++

Solution

You are not manipulating the bits correctly.

Values 0-15 require 4 bits max, but you are only shifting bits by 2 places, so you have room for handling values 0-3 only.

Lets break down your code, using 15 (`1111` in binary) as an example.

This code:

data = data << 2; //makes room for the input

Takes the existing data (32, which is `00100000` in binary), shifts it 2 places to the left, becomes `10000000`.

Then this code:

data = data | input1;

Adds the input (which you are not restricting in any way, per the assignment) in the lower bits, becoming `10001111`.

This code:

output1 = data >> 2;

Shifts the total bits by 2 places to the right, becoming `00100011`, which as you can see loses the lower two bits of the previous input value that has been stored.

Then this code:

cout << output1;

Outputs the remaining bits as-is, which consists of bits from two different values merged together, producing 35 as output.

So, you need to bit-shift in both directions by either 4 bits (the minimum needed to handle values 0-15, taking up 16 bits total) or 8 bits (the maximum allowed to fit 4 values into 32 bits). And in the case of right-shifting, you need to mask out bits that you don't want in the output.

Try something more like this instead:

Using 4-bit storage (the minimum needed for handling values 0-15):

#include <iostream>
#include <limits> 

using namespace std;

unsigned int getInput()
{
    unsigned int in;
    do
    {
        cout << "Input a number between 0-15 inclusive: ";
        if (cin >> in)
        {
            if ((in >= 0) && (in <= 15))
                break;
        }

        cin.clear();
        cin.ignore(numeric_limits<streamsize_t>::max(), '\n');
    }
    while (true);

    return in;
}

int main()
{
    unsigned int input1, input2, input3, input4;
    unsigned int packit, output;
    int which;

    input1 = getInput();
    input2 = getInput();
    input3 = getInput();
    input4 = getInput();

    packit = (input4 << 12) | (input3 << 8) | (input2 << 4) | input1;

    do
    {
        cout << "Which number to retrieve (1-4, or 0 to exit): ";
        if (cin >> which)
        {
            if (which == 0)
                break;

            if ((which >= 1) && (which <= 4))
            {
                output = ((packit >> (4*(which-1))) & 0x0F);
                cout << output << endl;
                continue;
            }
        }

        cin.clear();
        cin.ignore(numeric_limits<streamsize_t>::max(), '\n');
    }
    while (true);

    return 0;
}

Using 8-bit storage (the maximum allowed, which would actually allow for handling values 0-255 max):

#include <iostream>
#include <limits> 

using namespace std;

unsigned int getInput()
{
    unsigned int in;
    do
    {
        cout << "Input a number between 0-15 inclusive: "; // or 255
        if (cin >> in)
        {
            if ((in >= 0) && (in <= 15)) // or 255
                break;
        }

        cin.clear();
        cin.ignore(numeric_limits<streamsize_t>::max(), '\n');
    }
    while (true);

    return in;
}

int main()
{
    unsigned int input1, input2, input3, input4;
    unsigned int packit, output;
    int which;

    input1 = getInput();
    input2 = getInput();
    input3 = getInput();
    input4 = getInput();

    packit = (input4 << 24) | (input3 << 16) | (input2 << 8) | input1;

    do
    {
        cout << "Which number to retrieve (1-4, or 0 to exit): ";
        if (cin >> which)
        {
            if (which == 0)
                break;

            if ((which >= 1) && (which <= 4))
            {
                output = ((packit >> (8*(which-1))) & 0xFF);
                cout << output << endl;
                continue;
            }
        }

        cin.clear();
        cin.ignore(numeric_limits<streamsize_t>::max(), '\n');
    }
    while (true);

    return 0;
}

Problem

I need help with a programming lab assignment that I cant seem to figure out. The question is : Allow the user to input 4 integer values all between 0 and 15 inclusive. Store these 4 values into a single 32 bit integer named "packit" Allow the user to choose which of the 4 integers they wish to recover from "packit". An input of "1" will recover the first value input, a "2" the second, a "3" the third, etc. Use only bit manipulations to store and recover the values. This is what I have so far: ``` #include <iostream> using namespace std; int getInput(){ int in; cout << "Input a number: "; cin >> in; return in; } int main(){ int input1, input2, input3, input4; int output1, output2, output3, output4; unsigned int data = 32; // makes room for the 4 integers input1 = getInput(); input2 = getInput(); input3 = getInput(); input4 = getInput(); data = data << 2; //makes room for the input data = data | input1; output1 = data >> 2; cout << output1; return 0; } ``` I stopped at `output1` just to test it, and it doesn't work. However, this is what I have come to after trying for hours. I'm not sure what I am doing wrong. I'm following the notes I copied off the board in class. Any help would be appreciated.

Original source

Related problems