将C ++类型int16_t转换为int64_t而不修改基础二进制文件

时间:2016-11-10 22:17:28

标签: c++ binary

我正在尝试为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]

这将用于二进制搜索。

3 个答案:

答案 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,因为这是无符号的。请务必检查符号位。