我正在尝试为3D空间中的对象生成哈希码,以便可以使用二进制搜索算法在数组中快速找到它。
由于此数组中的每个对象都有一个唯一的XYZ位置,我想我可以使用这三个值来生成哈希码。我使用以下代码尝试生成哈希码。
int64_t generateCode(int16_t x, int16_t y, int16_t z) {
int64_t hashCode = z;//Set Z bits.
hashCode <<= 16;//Shift them 16 bits.
hashCode |= y;//Set Y bits.
hashCode <<= 16;//Shift them 16 bits.
hashCode |= x;//Set X bits.
}
现在我的问题就在这里。考虑以下代码的和平:
int16_t x = -1;
cout << "X: " << bitset<16>(x) << endl;//Prints the binary value of X.
int64_t y = x;//Set Y to X. This will automatically cast the types.
cout << "Y: " << bitset<64>(y) << endl;//Prints the binary value of Y.
该程序的输出如下:
X: 1111111111111111
Y: 1111111111111111111111111111111111111111111111111111111111111111
它保留数字的数值,但更改底层二进制文件以执行此操作。我不想修改那个二进制文件,所以我可以得到如下输出:
X: 1111111111111111
Y: 0000000000000000000000000000000000000000000000001111111111111111
通过这样做,我可以从XYZ值创建一个唯一的哈希码,如下所示:
Unused X Y Z
HashCode: [0000000000000000][0000000000000000][0000000000000000][0000000000000000]
这将用于二进制搜索。
答案 0 :(得分:2)
大多数编译器都会理解并优化它以实现您的实际需求:
int16_t a[4] = { 0, z, y, x };
int64_t res;
memcpy(&res, a, sizeof(res));
(编译器将理解memcpy
可以通过简单的64位内存操作来完成,而不是实际调用真实的memcpy
)
答案 1 :(得分:1)
首先将int16_t
转换为uint16_t
,然后将它们合并为最终投放到uint64_t
的{{1}}:
int64_t
int64_t generateCode(int16_t x, int16_t y, int16_t z) {
uint64_t hashCode = static_cast<uint16_t>(z);
hashCode <<= 16;
hashCode |= static_cast<uint16_t>(y);
hashCode <<= 16;
hashCode |= static_cast<uint16_t>(x);
return static_cast<int64_t>(hashCode);
}
/ int16_t
类型将是双补码表示法(7.20.1.1 C标准的第1段要求这样),因此将它们转换为int64_t
相同大小的将是一个小小的无操作。
答案 2 :(得分:0)
尝试int64_t y = (uint16_t) x;
这样做,它将确保添加的额外位为0而不是1,因为这是无符号的。请务必检查符号位。