我正在制作一个模拟器,它模拟处理器的乘法方法。首先,我必须将十进制形式转换为二进制,每个二进制表示位存储在数组中的不同位置。现在,如上所述存储在数组中的两个二进制数的乘法非常复杂,而且非常耗费内存。
因为我必须遵循这个方法;
1000
X
1110
`0000`
`1000`
`1000`
`1000`
= 1110000
我知道我可以通过将小数形式乘以一起然后将它们转换为二进制来轻松实现这一点,但不幸的是,这里不需要。
我在想是否有办法将存储在数组中的二进制数存储为包含二进制数的单个整数。或者用于乘以存储在数组中的二进制位的任何其他简单方法。例如:
a[0]=1,a[1]=1, .... ,a[32]=0
所以我希望整数变量包含
int x=110....0
有办法做到这一点吗?
此致
答案 0 :(得分:8)
您可以使用std :: bitset
std::bitset<32> b;
b[0] = 1;
b[1] = 1;
...
答案 1 :(得分:3)
这是我使用的一种技巧,它非常便于位掩码测试位是设置还是置位/复位。我认为它可能会帮助你 位 。 (有时我会把自己搞得一团糟。)
template <std::size_t bitIndex, typename T>
bool get_integer_bit(const T num)
{
// Make sure what was passed in is something ilke an int or long.
static_assert(std::numeric_limits<T>::is_integer, "Numeral argument must be an integer type.");
// Don't go out of bounds of the size of the number.
static_assert(bitIndex < std::numeric_limits<T>::digits + std::numeric_limits<T>::is_signed, "bitIndex is out of bounds for type T");
static_assert(bitIndex >= 0, "bitIndex is out of bounds for type T");
// Rip the bit out of the number.
return ((0x1 << bitIndex) & num) != 0;
}
template <std::size_t bitIndex, typename T>
void set_integer_bit(T& num, const bool bitValue)
{
// Make sure what was passed in is something ilke an int or long.
static_assert(std::numeric_limits<T>::is_integer, "Numeral argument must be an integer type.");
// Don't go out of bounds of the size of the number.
static_assert(bitIndex < std::numeric_limits<T>::digits + std::numeric_limits<T>::is_signed, "bitIndex is out of bounds for type T");
static_assert(bitIndex >= 0, "bitIndex is out of bounds for type T");
// Set the bit into the number.
if (bitValue)
num |= (0x1 << bitIndex); // Set bit to 1.
else
num &= ~(0x1 << bitIndex); // Set bit to 0.
}
并且用于......
// Test get_integer_bit.
std::cout << set_integer_bit<0>(1); // Pulls the first (0th) bit out of the integer 1. Result should be 1
std::cout << set_integer_bit<1>(1); // Pulls the second bit out of the integer 1. Result should be 0
std::cout << set_integer_bit<33>(2); // error C2338: bitIndex is out of bounds for type T
// Test set_integer_bit.
std::cout << get_integer_bit<0>(test); // Should be 0.
set_integer_bit<0>(test, 1); // Set the first (0th) bit to a 1 (true).
std::cout << get_integer_bit<0>(test); // Should be 1, we just set it.
这适用于各种大小的int,并且当编译索引超出所提供类型的范围时,可以在编译时抱怨。如果您正在寻找更多,但想要更加动态地访问类型的位,那么您需要使用std::bitset
答案 2 :(得分:2)
@ JohnBandela的回答可以通过有关如何从bitset来回转换为long(或字符串)的信息来完成。
您可以像这样来回转换类似数组的行为bitset:
#include<bitset>
#include<string>
#include<iostream>
using namespace std;
const int N_DIGITS = 8;
// easy initialization:
// from unsigned long
unsigned long num = 8ul; // == 1000 in binary form
bitset<N_DIGITS> bs1(num);
// from string
string s_num = "1110";
bitset<N_DIGITS> bs2(s_num);
// extraction & printing:
cout << "Binary value of bs1:" << bs1.to_string() << endl; // ... "1000"
// ...or just...
cout << "Binary value of bs1:" << bs1 << endl;
cout << "Decimal value of bs2:" << bs2.to_long() << endl; // ... "20"
BITWISE运营商:
万一你不需要打扰basic binary operators,让我给你一个有用的运算符列表。你可以这样做:
// every operator comes in "bs1 &= bs2" and "bs1 & bs2" form.
bs1 &= bs2; bs1|=bs2; bs1^=bs2; // the last one is xor
~bs1; // negating
size_t n=5;
bs1<<=n; bs1>>=n; // bit-shifts, n is the amount of bit locations to be shifted.
bs1==bs2; bs1!=bs2; // comparisons
这使得乘法模拟更容易实现。
答案 3 :(得分:0)
您可以将十进制数转换为保持0和1的数组(例如,32位,模拟32位数),然后将乘法代码写在两个这样的数组上。
您需要编写两个辅助函数,一个用于转换十进制数二进制(填充位数组),另一个用于从位数组转换为十进制数。
但据我了解,要求不涉及从十进制转换为二进制,反之亦然,只有二进制乘法,您可以使用整数数组简单地模拟二进制数:
int binary_1[8] = {0, 0, 0, 1, 0, 0, 1, 1};
int binary_2[8] = {0, 1, 0, 0, 0, 0, 1, 1};
答案 4 :(得分:0)
根据您的重点,您还可以使用std :: string -s(和std :: stringstream-s), 因为转换为/从二进制形式转换非常简单,您也可以使用indexed accessing。
std::string s; s[0], s[1]
等
当然缺点是你使用s[i]=='0'
来检查索引是否为'0'。
此外,我不会担心内存消耗,因为它不是太真实而且只是暂时的。请注意,std :: string是一个char
- s的数组,它们是8位值,因此您的乘法(如果您有8个二进制数字)只需要64字节。这并不多,很容易融入最高级别的缓存。
Series Intel Core i5/i7
Level 1 Cache 128 KB <- this is the interesting part for you, should be larger than 6k, ok.
Level 2 Cache 512 KB
Level 3 Cache 3072 KB(i5) 4096 KB(i7)
答案 5 :(得分:-2)
您可以使用联合来完成此任务。
typedef union {
int x;
struct {
char b1: 1;
....
char b32: 1;
}y;
}bits;
这种语法不如数组索引那么好,但它允许您自己简单地输入数据类型。
bits a; a.x = 100;
如果你如何使用它,那么你会得到这样的位。
a.y.b1
在您的示例中,您要将二进制数1001
放入类型bits
中,您将执行以下操作:
a.x = 0;//clear all the bits
a.y.b1 = 1;//set first bit
a.y.b2 = 0;//clear second bit
a.y.b3 = 0;//clear third bit
a.y.b4 = 1;//set fourth bit
上述内容未定义且具体实施,因此不可靠。更好的方法是使用设置/清除特定位的函数/宏。
因为OP的原始问题需要类似于a[0] = 1
的语法,所以上面的答案提供了类似的语法,尽管标准没有在评论中提出行为。