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只是为了测试它,但是它不起作用。但是,这是我尝试了几个小时后得到的。我不确定自己在做什么错。我正在听课上抄写的笔记。任何帮助,将不胜感激。
您可以通过位操作或联合来完成此操作。联合往往是更具可读性的方法。
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中有效。
要使用位操作,您需要同时执行移位和and或or操作,以正确检索和设置位。
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)
您没有正确操作这些位。
值 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)
| 归档时间: |
|
| 查看次数: |
4057 次 |
| 最近记录: |