#include <iostream>
#include <stdint.h>
#include <limits>
uint64_t combine(uint32_t low, uint32_t high)
{
return (((uint64_t) high) << 32) | ((uint64_t) low);
}
uint32_t high(uint64_t combined)
{
return combined >> 32;
}
uint32_t low(uint64_t combined)
{
uint64_t mask = std::numeric_limits<uint32_t>::max();
return mask & combined; // should I just do "return combined;" which gives same result?
}
union Id
{
struct
{
uint32_t index; // lower 32 bits
uint32_t type; // upper 32 bits
} split;
uint64_t unique_id;
};
#include <iostream>
#include <assert.h>
#include <sstream>
template <typename T>
std::string bits(T num)
{
const int num_bits = sizeof(num) * 8;
T maxPow = T(1) << (num_bits - 1);
std::stringstream ss;
for(int i=0; i < num_bits; ++i)
{
// print last bit and shift left.
ss << (num & maxPow ? 1 : 0);
if ((i+1) % 8 == 0) ss << " ";
num = num << 1;
}
return ss.str();
}
void test1()
{
{
int in_low = -3;
int in_high = 99;
uint64_t combined = combine(in_low, in_high);
std::cout << low(combined) << ", " << high(combined) << std::endl;
std::cout << bits(in_high) << bits(in_low) << std::endl;
std::cout << bits(combined) << std::endl;
}
{
uint32_t in_low = 3;
int in_high = -99;
uint64_t combined = combine(in_low, in_high);
std::cout << low(combined) << ", " << high(combined) << std::endl;
std::cout << bits(in_high) << bits(in_low) << std::endl;
std::cout << bits(combined) << std::endl;
}
{
uint32_t in_low = std::numeric_limits<uint32_t>::max();
int in_high = std::numeric_limits<int32_t>::min();
uint64_t combined = combine(in_low, in_high);
std::cout << low(combined) << ", " << high(combined) << std::endl;
std::cout << bits(in_high) << bits(in_low) << std::endl;
std::cout << bits(combined) << std::endl;
}
}
void test2() {
Id in; // would "Id in = {-3, 99};" be better? Is this legal C++03? Would a constructor be better?
in.split.type = -3;
in.split.index = 99;
std::cout << in.unique_id << std::endl; // prints 18446744060824649827
std::cout << bits(in.split.type) << bits(in.split.index) << std::endl;
std::cout << bits(in.unique_id) << std::endl; // prints 11111111 11111111 11111111 11111101 00000000 00000000 00000000 01100011
Id out;
out.unique_id = in.unique_id;
std::cout << int(out.split.type) << ", " << out.split.index << std::endl; // prints -3, 99
}
int main()
{
test1();
std::cout << "-------------------" << std::endl;
test2();
return 0;
}