#include <iostream>
#include <bitset>
using namespace std;
typedef unsigned short uint16_t;
typedef short int16_t;
#define CHAR_BIT 8
template <typename T,size_t count> static T convertBitSetToNumber( const std::bitset<count>& bitset )
{
T result;
#define targetSize (sizeof( T )*CHAR_BIT)
if ( targetSize > count )
{
// if bitset is 0xF00, converting it as 0x0F00 will lose sign information (0xF00 is negative, while 0x0F00 is positive)
// This is because sign bit is on the left.
// then, we need to add a zero (4bits) on the right and then convert 0xF000, later, we will divide by 16 (2^4) to preserve sign and value
size_t missingbits = targetSize - count;
std::bitset<targetSize> extended;
extended.reset(); // set all to 0
for ( size_t i = 0; i != count; ++i )
{
if ( i < count )
extended[i+missingbits] = bitset[i];
}
result = static_cast<T>( extended.to_ullong() );
int mask = 1 << (targetSize-missingbits-1);
mask |= mask - 1;
result = result >> missingbits;
result = result & mask;
return result;
}
else
{
return static_cast<T>( bitset.to_ullong() );
}
}
int main() {
uint16_t val1 = convertBitSetToNumber<uint16_t,12>( std::bitset<12>( "100010011010" ) );
// val1 is 0x089A
int16_t val2 = convertBitSetToNumber<int16_t,12>( std::bitset<12>( "100010011010" ) );
cout << std::hex << val1 << endl;
cout << std::hex << val2 << endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8Yml0c2V0Pgp1c2luZyBuYW1lc3BhY2Ugc3RkOwp0eXBlZGVmIHVuc2lnbmVkIHNob3J0IHVpbnQxNl90Owp0eXBlZGVmIHNob3J0IGludDE2X3Q7CiNkZWZpbmUgQ0hBUl9CSVQgOAoKdGVtcGxhdGUgPHR5cGVuYW1lIFQsc2l6ZV90IGNvdW50PiBzdGF0aWMgVCBjb252ZXJ0Qml0U2V0VG9OdW1iZXIoIGNvbnN0IHN0ZDo6Yml0c2V0PGNvdW50PiYgYml0c2V0ICkKewogICAgVCByZXN1bHQ7CiAgICAjZGVmaW5lIHRhcmdldFNpemUgKHNpemVvZiggVCApKkNIQVJfQklUKQogICAgaWYgKCB0YXJnZXRTaXplID4gY291bnQgKQogICAgewogICAgICAgIC8vIGlmIGJpdHNldCBpcyAweEYwMCwgY29udmVydGluZyBpdCBhcyAweDBGMDAgd2lsbCBsb3NlIHNpZ24gaW5mb3JtYXRpb24gKDB4RjAwIGlzIG5lZ2F0aXZlLCB3aGlsZSAweDBGMDAgaXMgcG9zaXRpdmUpCiAgICAgICAgLy8gVGhpcyBpcyBiZWNhdXNlIHNpZ24gYml0IGlzIG9uIHRoZSBsZWZ0LgogICAgICAgIC8vIHRoZW4sIHdlIG5lZWQgdG8gYWRkIGEgemVybyAoNGJpdHMpIG9uIHRoZSByaWdodCBhbmQgdGhlbiBjb252ZXJ0IDB4RjAwMCwgbGF0ZXIsIHdlIHdpbGwgZGl2aWRlIGJ5IDE2ICgyXjQpIHRvIHByZXNlcnZlIHNpZ24gYW5kIHZhbHVlCgogICAgICAgIHNpemVfdCBtaXNzaW5nYml0cyA9IHRhcmdldFNpemUgLSBjb3VudDsKCiAgICAgICAgc3RkOjpiaXRzZXQ8dGFyZ2V0U2l6ZT4gZXh0ZW5kZWQ7CiAgICAgICAgZXh0ZW5kZWQucmVzZXQoKTsgLy8gc2V0IGFsbCB0byAwCiAgICAgICAgZm9yICggc2l6ZV90IGkgPSAwOyBpICE9IGNvdW50OyArK2kgKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCBpIDwgY291bnQgKQogICAgICAgICAgICAgICAgZXh0ZW5kZWRbaSttaXNzaW5nYml0c10gPSBiaXRzZXRbaV07CiAgICAgICAgfQoKICAgICAgICByZXN1bHQgPSBzdGF0aWNfY2FzdDxUPiggZXh0ZW5kZWQudG9fdWxsb25nKCkgKTsKCQkKCQlpbnQgbWFzayA9IDEgPDwgKHRhcmdldFNpemUtbWlzc2luZ2JpdHMtMSk7CgkJbWFzayB8PSBtYXNrIC0gMTsKCQkKICAgICAgICByZXN1bHQgPSByZXN1bHQgPj4gbWlzc2luZ2JpdHM7CiAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICYgbWFzazsKCiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICByZXR1cm4gc3RhdGljX2Nhc3Q8VD4oIGJpdHNldC50b191bGxvbmcoKSApOwogICAgfQp9CgppbnQgbWFpbigpIHsKdWludDE2X3QgdmFsMSA9IGNvbnZlcnRCaXRTZXRUb051bWJlcjx1aW50MTZfdCwxMj4oIHN0ZDo6Yml0c2V0PDEyPiggIjEwMDAxMDAxMTAxMCIgKSApOwovLyB2YWwxIGlzIDB4MDg5QQppbnQxNl90IHZhbDIgPSBjb252ZXJ0Qml0U2V0VG9OdW1iZXI8aW50MTZfdCwxMj4oIHN0ZDo6Yml0c2V0PDEyPiggIjEwMDAxMDAxMTAxMCIgKSApOwoKCWNvdXQgPDwgc3RkOjpoZXggPDwgdmFsMSA8PCBlbmRsOwoJY291dCA8PCBzdGQ6OmhleCA8PCB2YWwyIDw8IGVuZGw7CglyZXR1cm4gMDsKfQ==