Reputation: 1663
I am making a simulator, which simulates the method of multiplication of a processor. The thing is first I have to convert the decimal form to binary, each bit of binary representation is stored at separate location in an array. Now the multiplication of two binary numbers, stored in arrays as mentioned above is very complex and also very memory consuming.
because I have to follow this method;
1000
x
1110
`0000`
`1000`
`1000`
`1000`
= 1110000
I know that I can easily do this by multiplying decimals forms together and then convert them to binary but unfortunately that's not required here.
I was thinking if there is a way to store the binary number stored in array as a single integer containing binary no. Or any other easy way for multiplying binary bits stored in array. For Example:
a[0]=1,a[1]=1, .... ,a[32]=0
so I want the integer variable to contain
int x=110....0
Is there a way to do this?
Regards
Upvotes: 2
Views: 14277
Reputation: 12514
@JohnBandela's answer can be completed with the info on how to convert back-and-forth from bitset to long (or string).
You can convert the array-like behaving bitset back-and-forth like this:
#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 OPERATORS:
Just in case you do not need to bother with basic binary operators, let me give you a list of useful operators. You can do:
// 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
This makes multiplication simulation much easier to implement.
Upvotes: 2
Reputation: 12514
Depending on what your focus is, you can also use std::string-s (and std::stringstream-s), since there the conversion to/from binary form is quite easy and you can use indexed accessing too.
std::string s; s[0], s[1]
, etc.
Of course the drawback is you use s[i]=='0'
to check whether an index is '0'.
Besides, I would not worry about memory consumption as it is not soo much really and only temporary. Note that std::string is an array of char
-s which are 8-bit values, therefore your multiplication (if you have 8 binary digits) takes only 64bytes. That is not much, fits easily into the highest level cache.
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)
Source: notebook check
Upvotes: 1
Reputation: 7179
This is a trick that I use that is very convenient for bitmasks to test whether a bit is set or set/reset a bit. I think it might help you quite a bit. (Sometimes I crack myself up.)
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.
}
And for the usage...
// 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.
This works for all sorts of sizes of int and has the benefit of complaining at compile time when the bit's index is outside the range of the type provided. If you are looking for a little more than that, though and want to more dynamically access the bits of a type and for that you would need to use a std::bitset
Upvotes: 4
Reputation: 3985
You can use a union to accomplish this.
typedef union {
int x;
struct {
char b1: 1;
....
char b32: 1;
}y;
}bits;
This syntax is not quite as nice as your array indexing, but it allows for your simple input into the data type it self.
bits a; a.x = 100;
If how you would use it then you would get to the bits like so.
a.y.b1
In your example say you want to put the binary number 1001
into the type bits
you would do the following:
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
The above is not defined and implementation specific and thus is not reliable. A better method would be to use a function/macro that would set/clear specific bits.
Because the OP's original question wanted a syntax similar to a[0] = 1
the above answer provides a similar syntax, although the behavior is not defined by the standard as brought up in the comments.
Upvotes: -2
Reputation: 13510
You can convert the decimal number to an array (say, 32 places, simulating a 32 bit number) holding 0s and 1s, then write the multiplication code over two such arrays.
You will need to write two helper function, one for converting the decimal number binary (fill the bits array) and another for converting from bits array to a decimal number.
But as I understand, requirement doesn't involve converting from decimal to binary and vice versa, only binary multiplication, you can simulate a binary number using an integer array simply by:
int binary_1[8] = {0, 0, 0, 1, 0, 0, 1, 1};
int binary_2[8] = {0, 1, 0, 0, 0, 0, 1, 1};
Upvotes: 0
Reputation: 2436
You can use std::bitset
std::bitset<32> b;
b[0] = 1;
b[1] = 1;
...
Upvotes: 9