位操作以在一个int C ++中存储多个值

n00*_*mer 1 c++ bit-manipulation

我需要我似乎无法弄清楚的编程实验室作业的帮助。

问题是 :

允许用户输入4个整数值(介于0和15之间)。将这4个值存储到一个名为“ packit”的32位整数中,允许用户从“ packit”中选择要恢复的4个整数中的哪个。输入“ 1”将恢复第一个值输入,输入“ 2”将恢复第二个值,“ 3”将恢复第三个值,等等。仅使用位操作来存储和恢复值。

这是我到目前为止的内容:

#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;
}
Run Code Online (Sandbox Code Playgroud)

我停下来output1只是为了测试它,但是它不起作用。但是,这是我尝试了几个小时后得到的。我不确定自己在做什么错。我正在听课上抄写的笔记。任何帮助,将不胜感激。

lcs*_*lcs 6

您可以通过位操作或联合来完成此操作。联合往往是更具可读性的方法。

union
{
  unsigned char[4] data;
  unsigned long packed;
} packit;

data[0] = 1;
data[1] = 1;
data[2] = 1;
data[3] = 1;

std::cout << "packit = " << packit.packed;
// packit = 16843009
// 00000001 00000001 00000001 00000001
Run Code Online (Sandbox Code Playgroud)

注意:通过联合的类型修剪仅在C中有效。

要使用位操作,您需要同时执行移位和andor操作,以正确检索和设置位。

unsigned long packit = 0;

// Set data0
packit |= data0;

// Set data1
packit |= (data1 << 8)

// Set data2
packit |= (data2 << 16)

// Set data3
packit |= (data3 << 24)
Run Code Online (Sandbox Code Playgroud)

阅读与设定相反。您需要清除所有值,除了要读取的值,然后将其移到正确的位置。

unsigned char data0 = (packit & 0x000000FF);
unsigned char data1 = (packit & 0x0000FF00) >> 8;
unsigned char data2 = (packit & 0x00FF0000) >> 16;
unsigned char data3 = (packit & 0xFF000000) >> 24;
Run Code Online (Sandbox Code Playgroud)

  • 在c ++中,不允许通过联合类型进行修饰。看到http://stackoverflow.com/a/25672839/969365 (3认同)

Rem*_*eau 6

您没有正确操作这些位。

值 0-15 最多需要 4 位,但您只需将位移动 2 位,因此您只有处理值 0-3 的空间。

让我们分解您的代码,以 15(1111二进制)为例。

这段代码:

data = data << 2; //makes room for the input
Run Code Online (Sandbox Code Playgroud)

获取现有数据(32,00100000二进制),将其向左移动 2 位,变为10000000

然后这段代码:

data = data | input1;
Run Code Online (Sandbox Code Playgroud)

在较低的位中添加输入(您没有以任何方式限制,根据分配),成为10001111.

这段代码:

output1 = data >> 2;
Run Code Online (Sandbox Code Playgroud)

将总位向右移动 2 位,变成00100011,如您所见,它丢失了先前存储的输入值的低两位。

然后这段代码:

cout << output1;
Run Code Online (Sandbox Code Playgroud)

按原样输出剩余的位,它由合并在一起的两个不同值的位组成,产生 35 作为输出。

因此,您需要在两个方向上移位 4 位(处理 0-15 值所需的最小值,总共占用 16 位)或 8 位(允许将 4 个值放入 32 位的最大值)。在右移的情况下,您需要屏蔽掉输出中不需要的位。

尝试更像这样的事情:

使用 4 位存储(处理 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;
}
Run Code Online (Sandbox Code Playgroud)

使用 8 位存储(允许的最大值,实际上允许处理 0-255 最大值):

#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;
}
Run Code Online (Sandbox Code Playgroud)