How can I convert a integer to its bit representation. I want to take an integer and return a vector that has contains 1's and 0's of the integer's bit representation.
I'm having a heck of a time trying to do this myself so I thought I would ask to see if there was a built in library function that could help.
Doesn't work with negatives.
vector<int> convert(int x) {
vector<int> ret;
while(x) {
if (x&1)
ret.push_back(1);
else
ret.push_back(0);
x>>=1;
}
reverse(ret.begin(),ret.end());
return ret;
}
It's not too hard to solve with a one-liner, but there is actually a standard-library solution.
#include <bitset>
#include <algorithm>
std::vector< int > get_bits( unsigned long x ) {
std::string chars( std::bitset< sizeof(long) * CHAR_BIT >( x )
.to_string< char, std::char_traits<char>, std::allocator<char> >() );
std::transform( chars.begin(), chars.end(),
std::bind2nd( std::minus<char>(), '0' ) );
return std::vector< int >( chars.begin(), chars.end() );
}
C++0x even makes it easier!
#include <bitset>
std::vector< int > get_bits( unsigned long x ) {
std::string chars( std::bitset< sizeof(long) * CHAR_BIT >( x )
.to_string( char(0), char(1) ) );
return std::vector< int >( chars.begin(), chars.end() );
}
This is one of the more bizarre corners of the library. Perhaps really what they were driving at was serialization.
cout << bitset< 8 >( x ) << endl; // print 8 low-order bits of x
A modification of DCP's answer. The behavior is implementation defined for negative values of t. It provides all bits, even the leading zeros. Standard caveats related to the use of std::vector<bool> and it not being a proper container.
#include <vector> //for std::vector
#include <algorithm> //for std::reverse
#include <climits> //for CHAR_BIT
template<typename T>
std::vector<bool> convert(T t) {
std::vector<bool> ret;
for(unsigned int i = 0; i < sizeof(T) * CHAR_BIT; ++i, t >>= 1)
ret.push_back(t & 1);
std::reverse(ret.begin(), ret.end());
return ret;
}
And a version that [might] work with floating point values as well. And possibly other POD types. I haven't really tested this at all. It might work better for negative values, or it might work worse. I haven't put much thought into it.
template<typename T>
std::vector<bool> convert(T t) {
union {
T obj;
unsigned char bytes[sizeof(T)];
} uT;
uT.obj = t;
std::vector<bool> ret;
for(int i = sizeof(T)-1; i >= 0; --i)
for(unsigned int j = 0; j < CHAR_BIT; ++j, uT.bytes[i] >>= 1)
ret.push_back(uT.bytes[i] & 1);
std::reverse(ret.begin(), ret.end());
return ret;
}
Here is a version that works with negative numbers:
string get_bits(unsigned int x)
{
string ret;
for (unsigned int mask=0x80000000; mask; mask>>=1) {
ret += (x & mask) ? "1" : "0";
}
return ret;
}
The string can, of course, be replaced by a vector or indexed for bit values.
Returns a string instead of a vector, but can be easily changed.
template<typename T>
std::string get_bits(T value) {
int size = sizeof(value) * CHAR_BIT;
std::string ret;
ret.reserve(size);
for (int i = size-1; i >= 0; --i)
ret += (value & (1 << i)) == 0 ? '0' : '1';
return ret;
}
The world's worst integer to bit as bytes converter:
#include <algorithm>
#include <functional>
#include <iterator>
#include <stdlib.h>
class zero_ascii_iterator: public std::iterator<std::input_iterator_tag, char>
{
public:
zero_ascii_iterator &operator++()
{
return *this;
}
char operator *() const
{
return '0';
}
};
char bits[33];
_itoa(value, bits, 2);
std::transform(
bits,
bits + strlen(bits),
zero_ascii_iterator(),
bits,
std::minus<char>());
Related
I have this program that encodes integer values:
#include "stdafx.h"
#define _SECURE_SCL_DEPRECATE 0
#include <iostream>
#include <list>
#include <vector>
#include <algorithm>
using namespace std;
template<class T>
vector<unsigned char> nToB(T );
unsigned long ByteToint(vector<unsigned char> v)
{
unsigned long int a = 0;
int s = v.size();
for (int i = 0; i<s ; i++)
{
a |= (v[s - 1 - i] << (8 * (s - i - 1)));
}
return a;
}
static unsigned long int Encode7Bits(unsigned long int);
int main()
{
cout << Encode7Bits(420);
getchar();
return 0;
}
static unsigned long int Encode7Bits( unsigned long int x)
{
vector<unsigned char> Result;
do
{
unsigned long int tmp = x & 0x7f;
x = x >> 7;
if (x > 0)
tmp |= 0x80;
Result.push_back((unsigned char )tmp);
} while (x > 0);
return ByteToint(Result);
}
If the argument to this function is 420 it will return 932.
My question is whether it is possible to do the reverse operation, a decoding function that given 932, returns 420.
No it isn't.
|= is non-invertible in the sense that if you write c = a | b, then given c, and either a or b, you can't recover the other variable.
The bitwise operators << and >> are obviously lossy since they introduce 0 bits.
You'll have better luck with XOR: if you write c = a ^ b, then c ^ b will be a.
I have a vector<int> of length n which contains only 0 and 1's. For example we can have the following vector of length 10:
0 1 1 0 1 0 0 1 0 0
Now I use the number represented by that vector to access a location in an array with 2^n entries (so in this case an array of 2^10 = 1024). I'm not sure how I can obtain one integer from the byte representation stored in this vector<int>.
Simply run through the vector and collect powers of 2.
It depends on which end of the vector you want as most significant digit but e.g.
auto to_int( const vector<int>& digits )
-> int
{
int result = 0;
for( int const digit : digits )
{
result += 2*result + digit;
}
return result;
}
Or the other way,
auto to_int( const vector<int>& digits )
-> int
{
int result = 0;
for( int i = (int)digits.size(); i --> 0; )
{
result += 2*result + digits[i];
}
return result;
}
Disclaimer: code not reviewed by compiler.
use a std::bitset (http://en.cppreference.com/w/cpp/utility/bitset) which has a to_ulong() method
Something like this:
int integer=0;
int c=0;
for(int i : intVector){
integer+=i<<c;
c++;
}
return integer;
A simply way using a for loop:
size_t val{0};
for (const auto i : vec)
val = (val << 1) + i;
You can keep the std::vector and use std::bitset:
#include <iostream>
#include <vector>
#include <bitset>
#include <algorithm>
#include <climits>
template <typename IterType>
unsigned long getValue(IterType i1, IterType i2)
{
unsigned long i = 0;
std::bitset<CHAR_BIT * sizeof(unsigned long)> b;
std::for_each(i1, i2, [&](auto n) { b.set(i++, n);});
return b.to_ulong();
}
int main()
{
std::vector<int> v = {0, 1, 1, 0, 1, 0, 0, 1, 0, 0};
auto val = getValue(v.rbegin(), v.rend());
std::cout << val << "\n";;
auto val2 = getValue(v.begin(), v.end());
std::cout << val2;
}
Note that depending on which bit is the most significant bit, you supply the iterators accordingly. For right-to-left, supply reverse iterators, otherwise supply forward iterators.
Live Example
I have a vector<bool> that contains 10 elements. How can I convert it to a binary type;
vector<bool> a={0,1,1,1,1,0,1,1,1,0}
I want to get binary values, something like this:
long long int x = convert2bin(s)
cout << "x = " << x << endl
x = 0b0111101110
Note: the size of vector will be change during run time, max size = 400.
0b is important, I want to use the gcc extension, or some literal type.
As I understood of comment
Yes it can even hold 400 values
And in question
0b is important
You need to have string, not int.
std::string convert2bin(const std::vector<bool>& v)
{
std::string out("0b");
out.reserve(v.size() + 2);
for (bool b : v)
{
out += b ? '1' : '0';
}
return i;
}
std::vector<bool> a = { 0, 1, 1, 1, 1, 0, 1, 1, 1, 0 };
std::string s = "";
for (bool b : a)
{
s += std::to_string(b);
}
int result = std::stoi(s);
If you really want to do this, you start from the end. Although I support Marius Bancila and advise to use a bitset instead.
int mValue = 0
for(int i=a.size()-1, pos=0; i>=0; i--, pos++)
{
// Here we create the bitmask for this value
if(a[i] == 1)
{
mask = 1;
mask << pos;
myValue |= mask;
}
}
Your x is just an integer form from a, so can use std::accumulate like following
long long x = accumulate(a.begin(), a.end(), 0,
[](long long p, long long q)
{ return (p << 1) + q; }
);
For a 400 size, you need a std::string though
First of all the result of the conversion is not a literal. So you may not use prefix 0b applied to variable x.
Here is an example
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <numeric>
#include <vector>
#include <iterator>
#include <limits>
int main()
{
std::vector<bool> v = { 0, 1, 1, 1, 1, 0, 1, 1, 1, 0 };
typedef std::vector<bool>::size_type size_type;
size_type n = std::min<size_type>( v.size(),
std::numeric_limits<long long>::digits + 1 );
long long x = std::accumulate( v.begin(), std::next( v.begin(), n ), 0ll,
[]( long long acc, int value )
{
return acc << 1 | value;
} );
for ( int i : v ) std::cout << i;
std::cout << std::endl;
std::cout << std::hex << x << std::endl;
return 0;
}
The output is
0111101110
1ee
vector<bool> is already a "binary" type.
Converting to an int is not possible for more bits than available in an int. However if you want to be able to print in that format, you can use a facet and attach it to the locale then imbue() before you print your vector<bool>. Ideally you will "store" the locale once.
I don't know the GNU extension for printing an int with 0b prefix but you can get your print facet to do that.
A simpler way is to create a "wrapper" for your vector<bool> and print that.
Although vector<bool> is always internally implemented as a "bitset" there is no public method to extract the raw data out nor necessarily a standard representation for it.
You can of course convert it to a different type by iterating through it, although I guess you may have been looking for something else?
If the number of bits is known in advance and by some reason you need to start from an std::array rather than from an std::bitset directly, consider this option (inspired by this book):
#include <sstream>
#include <iostream>
#include <bitset>
#include <array>
#include <iterator>
/**
* #brief Converts an array of bools to a bitset
* #tparam nBits the size of the array
* #param bits the array of bools
* #return a bitset with size nBits
* #see https://www.linuxtopia.org/online_books/programming_books/c++_practical_programming/c++_practical_programming_192.html
*/
template <size_t nBits>
std::bitset<nBits> BitsToBitset(const std::array<bool, nBits> bits)
{
std::ostringstream oss;
std::copy(std::begin(bits), std::end(bits), std::ostream_iterator<bool>(oss, ""));
return std::bitset<nBits>(oss.str());
}
int main()
{
std::array<bool, 10> a = { 0, 1, 1, 1, 1, 0, 1, 1, 1, 0 };
unsigned long int x = BitsToBitset(a).to_ulong();
std::cout << x << std::endl;
return x;
}
Is it possible to take an array filled with 2 digit numbers e.g.
[10,11,12,13,...]
and multiply each element in the list by 100^(position in the array) and sum the result so that:
mysteryFunction[10,11,12] //The function performs 10*100^0 + 11*100^1 + 12*100^3
= 121110
and also
mysteryFunction[10,11,12,13]
= 13121110
when I do not know the number of elements in the array?
(yes, the reverse of order is intended but not 100% necessary, and just in case you missed it the first time the numbers will always be 2 digits)
Just for a bit of background to the problem: this is to try to improve my attempt at an RSA encryption program, at the moment I am multiplying each member of the array by 100^(the position of the number) written out each time which means that each word which I use to encrypt must be a certain length.
For example to encrypt "ab" I have converted it to an array [10,11] but need to convert it to 1110 before I can put it through the RSA algorithm. I would need to adjust my code for if I then wanted to use a three letter word, again for a four letter word etc. which I'm sure you will agree is not ideal. My code is nothing like industry standard but I am happy to upload it should anyone want to see it (I have also already managed this in Haskell if anyone would like to see that). I thought that the background information was necessary just so that I don't get hundreds of downvotes from people thinking that I'm trying to trick them into doing homework for me. Thank you very much for any help, I really do appreciate it!
EDIT: Thank you for all of the answers! They perfectly answer the question that I asked but I am having problems incorporating them into my current program, if I post my code so far would you be able to help? When I tried to include the answer provided I got an error message (I can't vote up because I don't have enough reputation, sorry that I haven't accepted any answers yet).
#include <iostream>
#include <string>
#include <math.h>
int returnVal (char x)
{
return (int) x;
}
unsigned long long modExp(unsigned long long b, unsigned long long e, unsigned long long m)
{
unsigned long long remainder;
int x = 1;
while (e != 0)
{
remainder = e % 2;
e= e/2;
if (remainder == 1)
x = (x * b) % m;
b= (b * b) % m;
}
return x;
}
int main()
{
unsigned long long p = 80001;
unsigned long long q = 70021;
int e = 7;
unsigned long long n = p * q;
std::string foo = "ab";
for (int i = 0; i < foo.length(); i++);
{
std::cout << modExp (returnVal((foo[0]) - 87) + returnVal (foo[1] -87) * 100, e, n);
}
}
If you want to use plain C-style arrays, you will have to separately know the number of entries. With this approach, your mysterious function might be defined like this:
unsigned mysteryFunction(unsigned numbers[], size_t n)
{
unsigned result = 0;
unsigned factor = 1;
for (size_t i = 0; i < n; ++i)
{
result += factor * numbers[i];
factor *= 100;
}
return result;
}
You can test this code with the following:
#include <iostream>
int main()
{
unsigned ar[] = {10, 11, 12, 13};
std::cout << mysteryFunction(ar, 4) << "\n";
return 0;
}
On the other hand, if you want to utilize the STL's vector class, you won't separately need the size. The code itself won't need too many changes.
Also note that the built-in integer types cannot handle very large numbers, so you might want to look into an arbitrary precision number library, like GMP.
EDIT: Here's a version of the function which accepts a std::string and uses the characters' ASCII values minus 87 as the numbers:
unsigned mysteryFunction(const std::string& input)
{
unsigned result = 0;
unsigned factor = 1;
for (size_t i = 0; i < input.size(); ++i)
{
result += factor * (input[i] - 87);
factor *= 100;
}
return result;
}
The test code becomes:
#include <iostream>
#include <string>
int main()
{
std::string myString = "abcde";
std::cout << mysteryFunction(myString) << "\n";
return 0;
}
The program prints: 1413121110
As benedek mentioned, here's an implementation using dynamic arrays via std::vector.
unsigned mystery(std::vector<unsigned> vect)
{
unsigned result = 0;
unsigned factor = 1;
for (auto& item : vect)
{
result += factor * item;
factor *= 100;
}
return result;
}
void main(void)
{
std::vector<unsigned> ar;
ar.push_back(10);
ar.push_back(11);
ar.push_back(12);
ar.push_back(13);
std::cout << mystery(ar);
}
I would like to suggest the following solutions.
You could use standard algorithm std::accumulate declared in header <numeric>
For example
#include <iostream>
#include <numeric>
int main()
{
unsigned int a[] = { 10, 11, 12, 13 };
unsigned long long i = 1;
unsigned long long s =
std::accumulate( std::begin( a ), std::end( a ), 0ull,
[&]( unsigned long long acc, unsigned int x )
{
return ( acc += x * i, i *= 100, acc );
} );
std::cout << "s = " << s << std::endl;
return 0;
}
The output is
s = 13121110
The same can be done with using the range based for statement
#include <iostream>
#include <numeric>
int main()
{
unsigned int a[] = { 10, 11, 12, 13 };
unsigned long long i = 1;
unsigned long long s = 0;
for ( unsigned int x : a )
{
s += x * i; i *= 100;
}
std::cout << "s = " << s << std::endl;
return 0;
}
You could also write a separate function
unsigned long long mysteryFunction( const unsigned int a[], size_t n )
{
unsigned long long s = 0;
unsigned long long i = 1;
for ( size_t k = 0; k < n; k++ )
{
s += a[k] * i; i *= 100;
}
return s;
}
Also think about using std::string instead of integral numbers to keep an encrypted result.
I'm performing comparisons of objects based on the binary presence or absence of a set of features. These features can be represented by a bit string, such as this:
10011
This bitstring has the first, fourth and fifth feature.
I'm trying to calculate the similarity of a pair of bit strings as the number of features that both share in common. For a given set of bit strings I know that they'll all have the same length, but I don't know at compile time what that length will be.
For example, these two strings have two features in common, so I'd like the similarity function to return 2:
s(10011,10010) = 2
How do I efficiently represent and compare bit-strings in C++?
You can use the std::bitset STL class.
They can be built from bit strings, ANDed, and count the number of 1:
#include <string>
#include <bitset>
int main()
{
std::bitset<5> option1(std::string("10011")), option2(std::string("10010"));
std::bitset<5> and_bit = option1 & option2; //bitset will have 1s only on common options
size_t s = and_bit.count (); //return the number of 1 in the bitfield
return 0;
}
EDIT
If number of bits is unknown at compile time, you can use boost::dynamic_bitset<>:
boost::dynamic_bitset<> option(bit_string);
Other parts of example don't change, since boost::dynamic_bitset<> share a common interface with std::bitset.
Faster algorithm:
int similarity(unsigned int a, unsigned int b)
{
unsigned int r = a & b;
r = ( r & 0x55555555 ) + ((r >> 1) & 0x55555555 );
r = ( r & 0x33333333 ) + ((r >> 2) & 0x33333333 );
r = ( r & 0x0f0f0f0f ) + ((r >> 4) & 0x0f0f0f0f );
r = ( r & 0x00ff00ff ) + ((r >> 8) & 0x00ff00ff );
r = ( r & 0x0000ffff ) + ((r >>16) & 0x0000ffff );
return r;
}
int main() {
unsigned int a = 19 ;//10011
unsigned int b = 18 ;//10010
cout << similarity(a,b) << endl;
return 0;
}
Output:
2
Demonstration at ideone : http://www.ideone.com/bE4qb
As you don't know the bit length at compile time, you can use boost::dynamic_bitset instead of std::bitset.
You can then use operator& (or &=) to find the common bits, and count them using boost::dynamic_bitset::count().
The performance depends. For max speed, depending on your compiler, you may have to implement the loop yourself, e.g. using #Nawaz's method, or something from Bit Twiddling Hacks, or by writing the loop using assembler/compiler intrinsics for sse/popcount/etc.
Notice that at least llvm, gcc and icc detect many patterns of this sort and optimize the thing for you, so profile/check the generated code before doing manual work.
Use a std::bitset, if your set of features is less than the number of bits in a long (I think it's a long), you can get an unsigned long representation of the bits, then and the two values, and use bit twidling tricks from here to count.
If you want to continue to use strings to represent your bit pattern, you could do something like the following, using the zip_iterator from boost.
#include <iostream>
#include <string>
#include <algorithm>
#include <boost/tuple/tuple.hpp>
#include <boost/iterator/zip_iterator.hpp>
struct check_is_set :
public std::unary_function<const boost::tuple<char const&, char const&>&, bool>
{
bool operator()(const boost::tuple<char const&, char const&>& t) const
{
const char& cv1 = boost::get<0>(t);
const char& cv2 = boost::get<1>(t);
return cv1 == char('1') && cv1 == cv2;
}
};
size_t count_same(std::string const& opt1, std::string const& opt2)
{
std::string::const_iterator beg1 = opt1.begin();
std::string::const_iterator beg2 = opt2.begin();
// need the same number of items for end (this really is daft, you get a runtime
// error if the sizes are different otherwise!! I think it's a bug in the
// zip_iterator implementation...)
size_t end_s = std::min(opt1.size(), opt2.size());
std::string::const_iterator end1 = opt1.begin() + end_s;
std::string::const_iterator end2 = opt2.begin() + end_s;
return std::count_if(
boost::make_zip_iterator(
boost::make_tuple(beg1, beg2)
),
boost::make_zip_iterator(
boost::make_tuple(end1, end2)
),
check_is_set()
);
}
int main(void)
{
std::string opt1("1010111");
std::string opt2("001101");
std::cout << "same: " << count_same(opt1, opt2) << std::endl;
return 0;
}