私のゲーム用のメッシュリストの空間グリッドを作成しようとすると、特定のグリッドの座標データに基づいてユニークなハッシュを作成しようとしています。グリッドデータを取得しようとしています: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(...)
はうまく動作します。 1にそのバイトの左ビットおきである負のフリップをPOS_Y
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
注意:いずれかが負の場合しかし、私は、望ましくない効果を得ることができます。このようなことは、すべての数字が正の場合には起こりません。以下のコードでわかるように、私は手作業で符号ビットを反転させて、のビットをuint64_t
(コメントブロック)にコピーしました。それもうまくいかなかった。 (POS_Yのビットフィールドはのみ16バイト2のビットとBYTE3に影響を与えている)の上に、私は、私の[予想される]ビットフィールドのように見える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");
}
?ご協力いただきありがとうございます!
'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