我需要帮助完成我似乎无法解决的编程实验室任务。
问题是:
允许用户输入0到15之间的4个整数值。将这4个值存储到一个名为" packit"的32位整数中。允许用户选择他们希望从" packit"中恢复的4个整数中的哪一个。输入" 1"将恢复第一个值输入," 2"第二,a" 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;
}
我在output1
停留只是为了测试它,它不起作用。然而,这是我在尝试了几个小时之后来到的。我不确定我做错了什么。我跟着我在课堂上复制的笔记。
任何帮助将不胜感激。
答案 0 :(得分: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
注意:通过联合键入双关语仅在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)
阅读与设置相反。除了想要阅读的内容之外,您需要清除任何值并将其移动到正确的位置。
unsigned char data0 = (packit & 0x000000FF);
unsigned char data1 = (packit & 0x0000FF00) >> 8;
unsigned char data2 = (packit & 0x00FF0000) >> 16;
unsigned char data3 = (packit & 0xFF000000) >> 24;
答案 1 :(得分:3)
您没有正确操作这些位。
值0-15最多需要4位,但是您只将位移2位,因此您只有处理值0-3的空间。
让我们分析您的代码,使用15(二进制1111
)作为示例。
此代码:
data = data << 2; //makes room for the input
采用现有数据(32,二进制为00100000
),将其向左移2位,变为10000000
。
然后这段代码:
data = data | input1;
在较低位中添加输入(您没有以任何方式限制,根据分配),变为10001111
。
此代码:
output1 = data >> 2;
将总位数向右移动2位,变为00100011
,正如您所见,它会丢失已存储的上一个输入值的低两位。
然后这段代码:
cout << output1;
按原样输出剩余的比特,它由两个不同值合并在一起的比特组成,产生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;
}
使用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;
}
答案 2 :(得分:1)
你必须自己想一想,表示数字15需要多少位?
15 = 1111
它只需要4位。
现在你需要存储4个这样的数字...所以你需要16位。这意味着您甚至可以将所有这些数字存储在int
,short
或2 chars
中。按照你的要求,让我们使用整数。
好的,回到你的代码,
#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;
}
首先,unsigned int data = 32; // makes room for the 4 integers
。
这不会为您假设4个整数腾出空间。数字是32
二进制10000
。
为4个整数腾出空间,你真正想做的是,无论何时你想存储任何数字,你都要将整数中的位向左移4,然后使用按位或者按位存储数字。 (|
)不是=
所以这更像是你需要开始的东西:
unsigned int data = 0;
data = (data << 4)|input1;
data = (data << 4)|input2;
data = (data << 4)|input3;
现在要检索说input1
,我们这样做:
(data >> 8)&((1 << 4)-1)
<强>为什么吗
这是因为input1
之后是属于input2
和input3
的8位,所以我们将其删除,然后实际获取值,我们按位进行{{1} 1}}的15(1111),这是因为存储的数字的宽度不大于15,因为15是最接近这些数字的最小数字,并且由所有1&#39组成。
&
input2 == (data >> 2)&((1 << 4)-1)
希望有所帮助