在嘗試爲我的遊戲製作網格列表的空間網格時,我試圖根據特定網格的座標數據製作一個唯一的散列。我試圖拿走我的網格數據:WorldName world_name; uint8_t stage_index; short int pos_x; short int pos_y; short int pos_z;
並嘗試構建一個獨特的uint64_t hash_bitfield
。帶符號的int打破了較大位域的部分
我的uint64_t GenerateHash(...)
在我的網格座標爲正數時效果很好。然而,當任何是否定的,我得到的不良影響:
world: 1 -->> 0000 0001
stage: 1 -->> 0000 0001
pos_x: 23 -->> 0000 0000 0001 0111
pos_y: -23 -->> 1111 1111 1110 1001
pos_z: 23 -->> 0000 0000 0001 0111
[ world ] [ stage ] [ pos_x ] [ pos_y ] [ pos_z ]
--byte7-- --byte6-- --byte5-- --byte4-- --byte3-- --byte2-- --byte1-- --byte0--
1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 1001 0000 0000 0001 0111 <-- what I get
0000 0001 0000 0001 0000 0000 0001 0111 0000 0000 0001 0111 0000 0000 0001 0111 <-- when y is positive
What I expected: vvvvvvvvvvvvvvvvvvv
0000 0001 0000 0001 0000 0000 0001 0111 1111 1111 1110 1001 0000 0000 0001 0111
注意POS_Y爲負翻轉到1離開了那個字節的所有其他位。當所有數字都是正數時,不會發生這種情況。正如你在下面的代碼中看到的那樣,我試圖在之後手動翻轉的符號位,將這些位複製到uint64_t
(註釋塊)中。它也沒有工作。
#include <iostream>
#include <string>
#include <sstream>
#include <bitset>
using namespace std;
enum WorldName{ // These are collections of gameobj sectors
WORLD_TYPE1,
WORLD_TYPE2,
WORLD_TYPE3,
MAX_WORLDS
};
uint64_t GenerateHash(WorldName world_name, uint8_t stage_index, short int pos_x, short int pos_y, short int pos_z){
uint64_t world_name_t = world_name;
uint64_t stage_index_t = stage_index;
uint64_t pos_x_t = pos_x;
uint64_t pos_y_t = pos_y;
uint64_t pos_z_t = pos_z;
// Try to flip the sign manually (it doesn't help)
//uint64_t pos_x_t, pos_y_t, pos_z_t;
//if(pos_x < 0){ pos_x_t = ~(uint64_t(abs(pos_x))) + 1; } else { pos_x_t = pos_x; }
//if(pos_y < 0){ pos_y_t = ~(uint64_t(abs(pos_y))) + 1; } else { pos_y_t = pos_y; }
//if(pos_z < 0){ pos_z_t = ~(uint64_t(abs(pos_z))) + 1; } else { pos_z_t = pos_z; }
uint64_t hash_bitfield = 0x0;
hash_bitfield |= world_name_t << (8 * 7);
hash_bitfield |= stage_index_t << (8 * 6);
hash_bitfield |= pos_x_t << (8 * 4);
hash_bitfield |= pos_y_t << (8 * 2);
hash_bitfield |= pos_z_t;
return hash_bitfield;
}
void PrintBitString(std::string bitstr, std::string label="", bool print_ruler=true){
std::string buffer;
int count = 0;
for(size_t i = 0; i < bitstr.size(); i++){
buffer += bitstr[i];
count++;
if(count >3){ buffer += ' '; count = 0; }
}
if(print_ruler){
int num_of_bytes_to_draw = (bitstr.size()/8);
for(size_t k = num_of_bytes_to_draw; k > 0; --k){
cout << "--byte" << k - 1 << "-- ";
}
cout << endl;
}
cout << buffer << endl;
}
int main() {
WorldName world_name = (WorldName) 1; // 4B
uint8_t stage_index = 1; // 1B
short int pos_x = 23; // 2B
short int pos_y = -23; // 2B
short int pos_z = 23; // 2B
std::bitset<8> world_name_bits(world_name);
std::bitset<8> stage_index_bits(stage_index);
std::bitset<16> pos_x_bits(pos_x);
std::bitset<16> pos_y_bits(pos_y);
std::bitset<16> pos_z_bits(pos_z);
cout << "world: " << world_name << "\t-->> " << world_name_bits << endl;
cout << "stage: " << (int)stage_index << "\t-->> " << stage_index_bits << endl;
cout << "pos_x: " << pos_x << "\t-->> " << pos_x_bits << endl;
cout << "pos_y: " << pos_y << "\t-->> " << pos_y_bits << endl;
cout << "pos_z: " << pos_z << "\t-->> " << pos_z_bits << endl << endl;
uint64_t my_hash = GenerateHash(world_name, stage_index, pos_x, pos_y, pos_z);
uint64_t my_hash_abs = GenerateHash(world_name, stage_index, pos_x, abs(pos_y), pos_z);
cout << "[ world ] [ stage ] [ pos_x ] [ pos_y ] [ pos_z ]" << endl;
std::bitset<64> bits(my_hash);
std::bitset<64> bits_abs(my_hash_abs);
PrintBitString(bits.to_string());
PrintBitString(bits_abs.to_string(),"",false);
cout << endl;
system("PAUSE");
}
我怎樣才能得到一個uint64_t中,看起來像我的[預計]位域,以上(其中POS_Y的位域隻影響字節2的這些16位和字節3)?謝謝你的幫助!
by'unsigned short'你的意思是'uint16_t' –
這個技巧。這很簡單,我很慚愧,我沒有想到它。謝謝。 uint64_t pos_x_t = uint16_t(pos_x); uint64_t pos_y_t = uint16_t(pos_y); uint64_t pos_z_t = uint16_t(pos_z); – truthastup