Quickly Converting uint32_t to binary - c++

The main problem I'm having is to read out values in binary in C++ (python had some really quick/easy functions to do this)
I just need the same. So at the moment I have:
ValWord< uint32_t> data1=//[SOME READ FUNCTION]
When I use cout << data1; It gives me a number e.g 2147581953
I want this to be in binary and eventually each "bit" needs to be in its own bin including all '0's e.g:
for (int i = 31; i >= 0; i--) {
cout << binary[i];
}
Would give me this 32 bit long binary number. When I've had it as a straight forwward int, I've used:
int data[32];
bitset<32>(N) = data1;
for(int i=31; i >=0; i--) {
data[i]=(bitset<32>(N[i]).to_ulong());
}
for (int i = 31; i >= 0; i--) {
cout << data[i];
}
But this just gives me error messages. Any ideas?

Maybe this:
#define CPlusPlus11 0
#if CPlusPlus11
int main()
{
std::uint32_t value(42);
std::bitset<32> bits(value);
std::cout << bits.to_string() << std::endl;
// Storing integral values in the string:
for(auto i: bits.to_string(char(0), char(1))) {
std::cout << (int)i;
}
std::cout << std::endl;
return 0;
}
#else
int main()
{
std::uint32_t value(42);
std::bitset<32> bits(value);
std::cout << bits.to_string() << std::endl;
char data[32];
for(unsigned i = 0; i < 32; ++i) {
data[i] = bits[i];
}
for(unsigned i = 32; i; --i) {
std::cout << int(data[i-1]);
}
std::cout << std::endl;
return 0;
}
#endif
Note: Your expressions bitset<32>(N) = data1 and bitset<32>(N[i]) are code smell.

In general, transforming a number into a string for a given base, is quite ubiquitous:
#include <cassert>
#include <string>
static char const Digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
static size_t const DigitsSize = sizeof(Digits) - 1;
static size_t const BufferSize = 32;
std::string convert(unsigned number, unsigned base) {
assert(base >= 2 and base <= DigitsSize);
char buffer[BufferSize] = {};
char* p = buffer + BufferSize;
while (number != 0) {
*(--p) = Digits[number % base];
number /= base;
}
return std::string(p, (buffer + BufferSize) - p);
}
Note: BufferSize was computed for the minimum base of 2, base 1 and base 0 are non-sensical.
Note: if the number can be negative, the simplest is to test for it beforehand, and then use its opposite; a special caveat is that the opposite of the minimum value of a 32 bits integer cannot be represented by a 32 bits integer in base 2.

I have some simple functions i use for this, using stl, here is one for binary:
#include <iostream>
#include <algorithm>
using namespace std;
string binary( unsigned long n )
{
string result;
do result.push_back( '0' + (n & 1) );
while (n >>= 1);
reverse( result.begin(), result.end() );
return result;
}
int main()
{
cout << binary(1024) << endl;
cout << "Hello World" << endl;
return 0;
}
Hope this is of use to you!
Let me know if you need something more performant and I can try to rustle up some Assembler code for you.

Related

pHash returning different hash lenght

I have the following code:
fingerprint.cpp:
#include <iostream>
#include <filesystem>
#include "ImageHash.h"
#include "opencv2/core.hpp"
#include "opencv2/highgui.hpp"
#include <opencv2/imgcodecs.hpp>
using namespace std;
void usage (char** argv) noexcept {
cout << "Usage: " << argv[0] << " <image or dir>" << endl << "Example: " << argv[0] << " template.png" << endl;
}
int main(int argc, char** argv) {
if (argc != 2) {
usage(argv);
return 1;
}
auto imgHash = ImageHash();
if (std::filesystem::is_directory(argv[1])) {
for (const auto& dirEntry : std::filesystem::recursive_directory_iterator(argv[1])) {
auto filePath = dirEntry.path();
std::string fileName = dirEntry.path().filename().string();
cv::Mat img = cv::imread(filePath.string(), cv::IMREAD_GRAYSCALE);
img.resize(8*8);
/*cv::imshow("img", img);
cv::waitKey();*/
cout << fileName << "\t\t" << imgHash.getHashString(img) << endl;
}
}
else if (std::filesystem::is_regular_file(argv[1])){
cv::Mat img = cv::imread(argv[1], cv::IMREAD_GRAYSCALE);
cout << std::filesystem::path(argv[1]).filename().string() << "\t\t" << imgHash.getHashString(img) << endl;
}
else {
usage(argv);
}
return 0;
}
ImageHash.cpp:
#include "ImageHash.h"
#include <iomanip>
using namespace std;
ImageHash::ImageHash()
{
pHash = cv::img_hash::PHash::create();
}
std::string ImageHash::convertHashToString(vector<bool> hash) {
std::string ret = "";
double h = 0;
for (unsigned int i = 0; i < hash.size(); i++) {
if (hash[i]) {
h += pow(2, (i % 8));
}
if (i % 8 == 7) {
std::stringstream buffer;
buffer << std::hex << std::setfill('0') << std::setw(2) << h;
ret += buffer.str();
h = 0;
}
}
return ret;
}
std::vector<bool> ImageHash::hex_str_to_hash(std::string inputString) {
std::vector<bool> hash;
size_t size = inputString.size() / 2;
for (int i = 0; i < size; i++) {
std::string str2 = inputString.substr(i * 2, 2);
if (str2.empty()) {
continue;
}
unsigned int value = 0;
std::stringstream SS(str2);
SS >> std::hex >> value;
for (int j = 0; j < 8; j++) {
bool check = !!((value >> j) & 1);
hash.push_back(check);
}
}
return hash;
}
std::vector<bool> ImageHash::matHashToBoolArr(cv::Mat const inHash) {
const unsigned char* data = inHash.data;
std::vector<bool> v;
for (int i = 0; i < 8; i++) {
unsigned char c = data[i];
for (int j = 0; j < 8; j++) {
int shift = (8 - j) - 1;
bool val = ((c >> shift) & 1);
v.push_back(val);
}
}
return v;
}
std::vector<bool> ImageHash::computeHash(cv::Mat const input) {
cv::Mat inHash;
pHash->compute(input, inHash);
return matHashToBoolArr(inHash);
}
std::string ImageHash::getHashString(cv::Mat const input) {
return convertHashToString(computeHash(input));
}
//returns hamming distance
int ImageHash::getHashDistance(std::vector<bool>& hash1, std::vector<bool>& hash2) {
//assert(hash1.size() == hash2.size());
/* ToDo: I don't know why the size is not the same but if if is lets add padding to the smaller one
This does not seem to make it work*/
if (hash1.size() != hash2.size()) {
auto smaller = hash1.size() < hash2.size() ? &hash1 : &hash2;
auto larger = hash1.size() < hash2.size() ? hash2 : hash1;
smaller->resize(larger.size());
std::fill(begin(*smaller) + larger.size(), end(*smaller), 0);
}
int dist = 0;
for (unsigned int i = 0; i < hash1.size(); i++) {
dist += (hash1[i] != hash2[i]);
}
return dist;
}
For some reason the hashes returned have different size depending on the input image. I tried to add some padding at getHashDistance() but I don't think I should do that since now when I calculate the distance between two similar images I get a large distance as if they were not similar.
Do you know why that is? I'm resizing the images to 8*8 img.resize(8*8); which I though it would make the trick but it does not work.
Thanks
Thanks
auto imgHash = ImageHash();
Could it be that the auto keyword here is causing the runtime to draw different inferences of the returned type (and therefore the size of the returned type)?
Type Inference in C++ (auto and decltype)

my ascii to binary converter that i wrote in C++ displays binary backwards, how can i make it display right?

Ok so I wrote a ascii to binary converter in C++, everything is great, the only issue is that it displays the binary backwards, I don't know how to go about and display it right.
#include <iostream>
#include <string>
using namespace std;
int main() {
string word;
getline(cin, word);
for (int i = 0; word[i] != '\0'; i++) {
int v = int(word[i]);
while (v != 1 || 0) {
int m = v % 2;
cout << " " << m << " ";
v = v / 2;
}
cout << " " << v;
}
return 0;
}
So this is what I mean. When I run the code it asks for your input which is the ascii, so i input:
f
Which is 102 in decimal, hence it should display:
1100110
Instead i get:
0110011
What do i do?
In the following code, a bit mask is used to isolate the bit. The text form of the bit is then printed. The bit mask is then rotated in the appropriate direction.
const size_t length = word.length();
for (size_t i = 0; i < length; ++i)
{
char bit_mask = 0x80;
const char value(word[i]);
for (size_t bit_count = 0; bit_count < 8; ++bit_count)
{
char bit_value = value & bit_mask;
if (bit_value)
{
std::cout << '1';
}
else
{
std::cout << '0';
}
bit_mask >>= 1;
}
std::cout << ' ';
}
The above code prints bits in Most Significant Bit format. To change the bit order, change the initial value of the bit_mask and rotate the bit_mask left.

Change 'parameter' string inside method C++

it is my first question in SO, but I cannot find a good solution for this, not online nor from my brain.
I have a big string of number (over 100 digits) and I need to remove some of its digits to create a number divisible by 8. It is really simple...
However, lets say the only way to create this number is with a number that ends with '2'. In this case I would need to look for proper 10's and 100's digits and it is at this point I cannot find an elegant solution.
I have this:
bool ExistDigit(string & currentNumber, int look1) {
int currentDigit;
int length = currentNumber.length();
for (int i = length - 1; i >= 0; i--) {
currentDigit = -48;//0 in ASC II
currentDigit += currentNumber.back();//sum ASCII's value of char to current Digit
if (currentDigit == look1) {
return true;
}
else
currentNumber.pop_back;
}
return false;
}
It modify the string but since I check for 8's and 0's first, by the time I get to check 2's, the string is empty already. I solved this by creating several copies of the string, but I would like to know if there is a better way and what is it.
I know that if I use ExistDigit(string CurrentNumber, int look1), the string does not get modified, but in this case, it would not help with the 2, because after finding the two I need to look for 1's, 5's and 9's after the 2 in the original string.
What is the correct approach to these kind of problems? I mean, should I stick with changing the string or should I return a value for the position of the 2 (for example) and work from there? If it is good to change the string, how should I do it in order to be able to reuse the original string?
I am new to C++, and coding in general (just started actually) so, sorry if it is a really silly question. Thanks in advance.
EDIT: My call look like this:
int main() {
string originalNumber;//hold number. Must be string because number can be too long for ints
cin >> originalNumber;
string answer = "YES";
string strNumber;
//look for 0's and 8's. they are solutions by their own
strNumber = originalNumber;
if (ExistDigit(strNumber, 0)) {
answer += "\n0";
}
else {
strNumber = originalNumber;
if (ExistDigit(strNumber, 8)) {
answer += "\n8";
}
else {
strNumber = originalNumber;
//look for 'even'32, 'even'72, 'odd'12, 'odd'52, 'odd'92
//these are the possibilities for multiples of 8 ended with 2
if (ExistDigit(strNumber, 2)) {
if (ExistDigit(strNumber, 1)) {
}
}
else {
EDIT 2: In case you have the same problem, check the function find_last_of, it is really convenient and solves the problem.
The following code retains your design and should give at least a solution if one exists. The nested if and for can be simplified within a more elegant solution by using a recursive function. With such a recursive function, you could also enumerate all the solutions.
Instead of having multiple copies of the string, you could use an iterator that defines the start of the search. In the code the start variable is this iterator.
#include <string>
#include <iostream>
#include <sstream>
using namespace std;
bool ExistDigit(const string & currentNumber, int& start, int look1) {
int currentDigit;
int length = currentNumber.length();
for (int i = length - 1 - start; i >= 0; i--) {
currentDigit = currentNumber[i] - '0';
if (currentDigit == look1) {
start = length - i;
return true;
}
}
return false;
}
int main() {
string originalNumber;//hold number. Must be string because number can be too long for ints
cin >> originalNumber;
stringstream answer;
answer << "YES";
//look for 0's and 8's. they are solutions by their own
int start = 0;
if (ExistDigit(originalNumber, start, 0)) {
answer << "\n0";
}
else {
start = 0;
if (ExistDigit(originalNumber, start, 8)) {
answer << "\n8";
}
else {
start = 0;
//look for 'even'32, 'even'72, 'odd'12, 'odd'52, 'odd'92
//these are the possibilities for multiples of 8 ended with 2
if (ExistDigit(originalNumber, start, 2)) {
for (int look2 = 1; look2 < 10; look2 += 4) {
int startAttempt1 = start;
if (ExistDigit(originalNumber, startAttempt1, look2)) { // 'odd'
for (int look3 = 1; look3 < 10; look3 += 2) {
int startAttempt2 = startAttempt1;
if (ExistDigit(originalNumber, startAttempt2, look3))
answer << "\n" << look3 << look2 << "2";
};
}
};
for (int look2 = 3; look2 < 10; look2 += 4) {
int startAttempt1 = start;
if (ExistDigit(originalNumber, startAttempt1, look2)) // 'even'
answer << "\n" << look2 << "2";
};
}
//look for 'odd'36, 'odd'76, 'even'12, 'even'52, 'even'92
//these are the possibilities for multiples of 8 ended with 2
else if (ExistDigit(originalNumber, start, 6)) {
for (int look2 = 3; look2 < 10; look2 += 4) {
int startAttempt1 = start;
if (ExistDigit(originalNumber, startAttempt1, look2)) { // 'odd'
for (int look3 = 1; look3 < 10; look3 += 2) {
int startAttempt2 = startAttempt1;
if (ExistDigit(originalNumber, startAttempt2, look3))
answer << "\n" << look3 << look2 << "6";
};
}
};
for (int look2 = 1; look2 < 10; look2 += 4) {
int startAttempt1 = start;
if (ExistDigit(originalNumber, startAttempt1, look2)) // 'even'
answer << "\n" << look2 << "6";
};
}
//look for 'even'24, 'even'64, 'odd'44, 'odd'84, 'odd'04
//these are the possibilities for multiples of 8 ended with 2
else if (ExistDigit(originalNumber, start, 6)) {
for (int look2 = 0; look2 < 10; look2 += 4) {
int startAttempt1 = start;
if (ExistDigit(originalNumber, startAttempt1, look2)) { // 'odd'
for (int look3 = 1; look3 < 10; look3 += 2) {
int startAttempt2 = startAttempt1;
if (ExistDigit(originalNumber, startAttempt2, look3))
answer << "\n" << look3 << look2 << "4";
};
}
};
for (int look2 = 2; look2 < 10; look2 += 4) {
int startAttempt1 = start;
if (ExistDigit(originalNumber, startAttempt1, look2)) // 'even'
answer << "\n" << look2 << "4";
};
}
}
}
cout << answer.str() << std::endl;
return 0;
}
Here is a solution when you are looking for a subword composed of successive characters in the decimal textual form.
#include <string>
#include <iostream>
bool ExistDigit(const std::string& number, int look) { // look1 = 2**look
// look for a subword of size look that is divisible by 2**look = 1UL << look
for (int i = (int) number.size()-1; i >= 0; --i) {
bool hasFound = false;
unsigned long val = 0;
int shift = look-1;
if (i-shift <= 0)
shift = i;
for (; shift >= 0; --shift) {
val *= 10;
val += (number[i-shift] - '0');
};
if (val % (1UL << look) == 0)
return true;
};
return false;
}
int main(int argc, char** argv) {
std::string val;
std::cin >> val;
if (ExistsDigit(val, 3) /* since 8 = 2**3 = (1 << 3) */)
std::cout << "have found a decimal subword divisible by 8" << std::endl;
else
std::cout << "have not found any decimal subword divisible by 8" << std::endl;
return 0;
}
If you are likely to find a subword of consecutive bits in the binary form of the number, you need to convert your number in a big integer and then to do similar search.
Here is a (minimal-tested) solution without any call to an external library like gmp to convert the text in a big integer. This solution makes use of bitwise operations (<<, &).
#include <iostream>
#include <string>
#include <vector>
int
ExistDigit(const std::string & currentNumber, int look) { // look1 = 2^look
std::vector<unsigned> bigNumber;
int length = currentNumber.size();
for (int i = 0; i < length; ++i) {
unsigned carry = currentNumber[i] - '0';
// bigNumber = bigNumber * 10 + carry;
for (int index = 0; index < bigNumber.size(); ++index) {
unsigned lowPart = bigNumber[index] & ~(~0U << (sizeof(unsigned)*4));
unsigned highPart = bigNumber[index] >> (sizeof(unsigned)*4);
lowPart *= 10;
lowPart += carry;
carry = lowPart >> (sizeof(unsigned)*4);
lowPart &= ~(~0U << (sizeof(unsigned)*4));
highPart *= 10;
highPart += carry;
carry = highPart >> (sizeof(unsigned)*4);
highPart &= ~(~0U << (sizeof(unsigned)*4));
bigNumber[index] = lowPart | (highPart << (sizeof(unsigned)*4));
}
if (carry)
bigNumber.push_back(carry);
};
// here bigNumber should be a biginteger = currentNumber
for (int i = 0; i < bigNumber.size()*8*sizeof(unsigned); ++i) {
// looks for look consective bits set to '0'
bool hasFound = true;
for (int shift = 0; hasFound && shift < look; ++shift)
if (bigNumber[(i+shift) / (8*sizeof(unsigned))]
& (1U << ((i+shift) % (8*sizeof(unsigned)))) != 0)
hasFound = false;
if (hasFound) { // ok, bigNumber has look consecutive bits set to 0
// test if we are at the end of the bigNumber
int index = (i+look) / (8*sizeof(unsigned));
for (int j = ((i+look+8*sizeof(unsigned)-1) % (8*sizeof(unsigned)))+1;
j < (8*sizeof(unsigned)); j++)
if ((bigNumber[index] & (1U << j)) != 0)
return i; // the result is (currentNumber / (2^i));
while (++index < bigNumber.size())
if (bigNumber[index] != 0)
return i; // the result is (currentNumber / (2^i));
return -1;
};
};
return -1;
}
int main(int argc, char** argv) {
std::string val;
std::cin >> val;
std::cout << val << " is divided by 8 after " << ExistDigit(val, 3) << " bits." << std::endl;
return 0;
}

Missing punctuation from C++ hex2bin

While trying to duplicate PHP's bin2hex($s) and pack('H*',$s) (aka hex2bin($s) in PHP 5.4.3+) in GCC/Linux C++, I seem to have it figured out except that it's dropping punctuation for some strange reason. Can you figure out what I might be doing wrong in the hex2bin() function? I compared PHP's bin2hex() with mine and it appears to be working there properly, so the problem is in hex2bin().
#include <strings.h>
#include <string>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
string bin2hex(string s) {
int nLen = s.length();
string sOut;
char cBuff[2];
for (int i = 0; i < nLen; i++) {
sprintf(cBuff,"%.2x",s[i]);
sOut.append(cBuff);
cBuff[0] = '\0';
}
return sOut;
}
string hex2bin(string s) {
int nLen = s.length();
string sOut;
char cBuff1[2];
char cBuff2[2];
char cBuff[1];
int n,n1,n2;
for (int i = 0; i <= nLen; i+=2) {
sprintf(cBuff1,"%c",s[i]);
sprintf(cBuff2,"%c",s[i+1]);
n1 = atoi(cBuff1);
n2 = atoi(cBuff2);
n = (n1 * 16) + n2;
sprintf(cBuff,"%c",n);
sOut.append(cBuff);
cBuff[0] = '\0';
cBuff1[0] = '\0';
cBuff2[0] = '\0';
}
return sOut;
}
int main() {
string s;
string sResult;
s = "This is a 123 test.";
sResult = bin2hex(s);
printf("ENCODED: %s\n",sResult.c_str());
sResult = hex2bin(sResult);
printf("UNENCODED: %s\n",sResult.c_str());
return 1;
}
This emits:
ENCODED: 5468697320697320612031323320746573742e
UNENCODED: This is a 123 test
Okay, sleeves rolled up: let's look at C++ version:
Live on Coliru
Don't use C strings unless you need to (sprintf to build a two-char string is not... very efficient)
Use iostreams to encode/decode the hex digits (std::hex)
The hex2bin could optimized, but I went for "simpler"
I added a modicum of input sanitizing on hex2bin
#include <string>
#include <sstream>
#include <iomanip>
std::string bin2hex(std::string const &s) {
std::ostringstream oss;
for (unsigned char ch : s)
oss << std::hex << std::setw(2) << std::setfill('0') << (int) ch;
return oss.str();
}
#include <cassert>
std::string hex2bin(std::string const& s) {
assert(s.length() % 2 == 0);
std::string sOut;
sOut.reserve(s.length()/2);
std::string extract;
for (std::string::const_iterator pos = s.begin(); pos<s.end(); pos += 2)
{
extract.assign(pos, pos+2);
sOut.push_back(std::stoi(extract, nullptr, 16));
}
return sOut;
}
#include <iostream>
int main() {
std::cout << "ENCODED: " << bin2hex("This is a 123 test.") << "\n";
std::cout << "DECODED: " << hex2bin(bin2hex("This is a 123 test.")) << "\n";
}
Output:
ENCODED: 5468697320697320612031323320746573742e
DECODED: This is a 123 test.
With all but the period '.' you just went lucky: the hex digits didn't use an actual hexadecimal value. However, for the period you got 2e but you tried to decode the e using atoi("e"), roughly: that won't work as atoi() requires a decimal value. You could use strtol(str, 0, 16) instead to decode the hexadecimal value.
Note that you have a few buffer overruns when you are using sprintf(): this function writes a terminating null character. In general, you are much better off to snprintf() to avoid buffer overruns. Also, in your decoding routine you access values beyond the end of your string (you use i <= nLen with nLen = s.length() and then access s[i] and s[i+1]). Of course, the code is far too complex:
#include <string>
#include <sstream>
#include <iostream>
#include <iomanip>
std::string bin2hex(std::string s) {
std::ostringstream out;
out << std::hex << std::setfill('0');
for (char c: s) {
out << std::setw(2) << int(c);
}
return out.str();
}
std::string hex2bin(std::string s) {
std::string rc;
int nLen = s.length();
int tmp;
for (int i(0); i + 1 < nLen; i += 2) {
if (std::istringstream(s.substr(i, 2)) >> std::hex >> tmp) {
rc.push_back(tmp);
}
}
return rc;
}
int main() {
std::string s;
std::string sResult;
s = "This is a 123 test.";
sResult = bin2hex(s);
std::cout << "ENCRYPTED: " << sResult << '\n';
sResult = hex2bin(sResult);
std::cout << "UNENCRYPTED: " << sResult << '\n';
return 1;
}
Your code does not convert hexadecimal digits correctly because atoi can only handle decimal digits. Try this
sprintf(cBuff1,"%c",s[i]);
sprintf(cBuff2,"%c",s[i+1]);
n1 = strtoul(cBuff1, 0, 16);
n2 = strtoul(cBuff2, 0, 16);
Also your for loop should be
for (int i = 0; i < nLen; i+=2) {
n1 = atoi(cBuff1);
n2 = atoi(cBuff2);
n = (n1 * 16) + n2;
if cbuff1 is, say, "a", then this won't work, since a is not a digit. It works fine for digits that are '0-9', but not 'a-f'.
You will need to translate non-digits to numeric values.
There are quite a few ways to convert a hex value string to a byte. I think this is pretty decent:
int hexchar(char c)
{
if (c >= '0' && c <= '9') return c - '0';
// if you need to support upper-case hex:
// c = tolower(c);
if (c >= 'a' && c <= 'f') return c - 'a' + 10;
// If we get here, panic
cout << "Error, invalid hex digit:" << c << endl;
return -1;
}
int hexbyte(string s)
{
for(i = 0; i < s.length(); i+=2)
{
char c = hexbyte(s[i]);
c <<= 4;
c += hexbyte(s[i+1];
cout << c;
}
}
Try these trivial routines, good for C and C ++
/*------------------------------------------+
| bin2hex bin2hex bin2hex |
+------------------------------------------*/
static char *bin2hex(unsigned char *s, long L)
{
static char hex[2048];
long i,l=0;
for (i=0; i<L; i++) l+=sprintf(&hex[l], "%02x", 0xFF & (*(s+i)));
hex[l]=0;
return hex;
}
/*------------------------------------------+
| hex2bin hex2bin hex2bin |
+------------------------------------------*/
static char *hex2bin( char *s)
{
static char bin[2048];
unsigned int i,e,l=0,L=strlen(s);
for (i=0; i<L; i+=2) { sscanf(s+i, "%02x",&e); bin[l++]=(char)e; }
bin[l]=0;
return bin;
}

Converting string of 1s and 0s into binary value

I'm trying to convert an incoming sting of 1s and 0s from stdin into their respective binary values (where a string such as "11110111" would be converted to 0xF7). This seems pretty trivial but I don't want to reinvent the wheel so I'm wondering if there's anything in the C/C++ standard libs that can already perform such an operation?
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char * ptr;
long parsed = strtol("11110111", & ptr, 2);
printf("%lX\n", parsed);
return EXIT_SUCCESS;
}
For larger numbers, there as a long long version, strtoll.
You can use std::bitset (if then length of your bits is known at compile time)
Though with some program you could break it up into chunks and combine.
#include <bitset>
#include <iostream>
int main()
{
std::bitset<5> x(std::string("01011"));
std::cout << x << ":" << x.to_ulong() << std::endl;
}
You can use strtol
char string[] = "1101110100110100100000";
char * end;
long int value = strtol (string,&end,2);
You can use Boost Dynamic Bitset:
boost::dynamic_bitset<> x(std::string("01011"));
std::cout << x << ":" << x.to_ulong() << std::endl;
#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;
string getBinaryString(int value, unsigned int length, bool reverse) {
string output = string(length, '0');
if (!reverse) {
for (unsigned int i = 0; i < length; i++) {
if ((value & (1 << i)) != 0) {
output[i] = '1';
}
}
}
else {
for (unsigned int i = 0; i < length; i++) {
if ((value & (1 << (length - i - 1))) != 0) {
output[i] = '1';
}
}
}
return output;
}
unsigned long getInteger(const string& input, size_t lsbindex, size_t msbindex) {
unsigned long val = 0;
unsigned int offset = 0;
if (lsbindex > msbindex) {
size_t length = lsbindex - msbindex;
for (size_t i = msbindex; i <= lsbindex; i++, offset++) {
if (input[i] == '1') {
val |= (1 << (length - offset));
}
}
}
else { //lsbindex < msbindex
for (size_t i = lsbindex; i <= msbindex; i++, offset++) {
if (input[i] == '1') {
val |= (1 << offset);
}
}
}
return val;
}
int main() {
int value = 23;
cout << value << ": " << getBinaryString(value, 5, false) << endl;
string str = "01011";
cout << str << ": " << getInteger(str, 1, 3) << endl;
}