fork(1) download
  1. #include <iostream>
  2. #include <stdint.h>
  3. #include <limits>
  4.  
  5. uint64_t combine(uint32_t low, uint32_t high)
  6. {
  7. return (((uint64_t) high) << 32) | ((uint64_t) low);
  8. }
  9.  
  10. uint32_t high(uint64_t combined)
  11. {
  12. return combined >> 32;
  13. }
  14.  
  15. uint32_t low(uint64_t combined)
  16. {
  17. uint64_t mask = std::numeric_limits<uint32_t>::max();
  18. return mask & combined; // should I just do "return combined;" which gives same result?
  19. }
  20.  
  21. union Id
  22. {
  23. struct
  24. {
  25. uint32_t index; // lower 32 bits
  26. uint32_t type; // upper 32 bits
  27. } split;
  28.  
  29. uint64_t unique_id;
  30. };
  31.  
  32. #include <iostream>
  33. #include <assert.h>
  34. #include <sstream>
  35.  
  36. template <typename T>
  37. std::string bits(T num)
  38. {
  39. const int num_bits = sizeof(num) * 8;
  40.  
  41. T maxPow = T(1) << (num_bits - 1);
  42.  
  43. std::stringstream ss;
  44.  
  45. for(int i=0; i < num_bits; ++i)
  46. {
  47. // print last bit and shift left.
  48. ss << (num & maxPow ? 1 : 0);
  49. if ((i+1) % 8 == 0) ss << " ";
  50. num = num << 1;
  51. }
  52.  
  53. return ss.str();
  54. }
  55.  
  56. void test1()
  57. {
  58. {
  59. int in_low = -3;
  60. int in_high = 99;
  61. uint64_t combined = combine(in_low, in_high);
  62. std::cout << low(combined) << ", " << high(combined) << std::endl;
  63. std::cout << bits(in_high) << bits(in_low) << std::endl;
  64. std::cout << bits(combined) << std::endl;
  65. }
  66.  
  67. {
  68. uint32_t in_low = 3;
  69. int in_high = -99;
  70. uint64_t combined = combine(in_low, in_high);
  71. std::cout << low(combined) << ", " << high(combined) << std::endl;
  72. std::cout << bits(in_high) << bits(in_low) << std::endl;
  73. std::cout << bits(combined) << std::endl;
  74. }
  75.  
  76. {
  77. uint32_t in_low = std::numeric_limits<uint32_t>::max();
  78. int in_high = std::numeric_limits<int32_t>::min();
  79. uint64_t combined = combine(in_low, in_high);
  80. std::cout << low(combined) << ", " << high(combined) << std::endl;
  81. std::cout << bits(in_high) << bits(in_low) << std::endl;
  82. std::cout << bits(combined) << std::endl;
  83. }
  84. }
  85.  
  86. void test2() {
  87. Id in; // would "Id in = {-3, 99};" be better? Is this legal C++03? Would a constructor be better?
  88. in.split.type = -3;
  89. in.split.index = 99;
  90.  
  91. std::cout << in.unique_id << std::endl; // prints 18446744060824649827
  92. std::cout << bits(in.split.type) << bits(in.split.index) << std::endl;
  93. std::cout << bits(in.unique_id) << std::endl; // prints 11111111 11111111 11111111 11111101 00000000 00000000 00000000 01100011
  94.  
  95. Id out;
  96. out.unique_id = in.unique_id;
  97. std::cout << int(out.split.type) << ", " << out.split.index << std::endl; // prints -3, 99
  98. }
  99.  
  100. int main()
  101. {
  102. test1();
  103. std::cout << "-------------------" << std::endl;
  104. test2();
  105. return 0;
  106. }
Success #stdin #stdout 0s 3284KB
stdin
Standard input is empty
stdout
4294967293, 99
00000000 00000000 00000000 01100011 11111111 11111111 11111111 11111101 
00000000 00000000 00000000 01100011 11111111 11111111 11111111 11111101 
3, 4294967197
11111111 11111111 11111111 10011101 00000000 00000000 00000000 00000011 
11111111 11111111 11111111 10011101 00000000 00000000 00000000 00000011 
4294967295, 2147483648
10000000 00000000 00000000 00000000 11111111 11111111 11111111 11111111 
10000000 00000000 00000000 00000000 11111111 11111111 11111111 11111111 
-------------------
18446744060824649827
11111111 11111111 11111111 11111101 00000000 00000000 00000000 01100011 
11111111 11111111 11111111 11111101 00000000 00000000 00000000 01100011 
-3, 99