如何使用2个指针形成64位数?

时间:2015-06-12 14:12:03

标签: c pointers

假设我有两个指针

uint64_t* ptr1;
uint64_t* ptr2;

我必须形成一个var值,使得从ptr1获取6个字节,从ptr2获取2个字节,并且当前ptr1已经消耗了它的初始2个字节,现在剩下要处理的剩余字节是6个字节。

我写了这样的东西

uint64_t value = (uint64_t)((*ptr1) >> 16);\
value = (uint64_t)(value << 16 | (*ptr2 & 0x000000000000ffff));\

理想情况下,它的掩码应该是0xffff000000000000,但它不起作用。(出于处理目的)。我该怎么办?我在这里做错了什么? 据我说它应该只是

value = (uint64_t)((*ptr1 & ~0x000000000000ffff)  << 16 | (*ptr2 & 0xffff000000000000));

编辑:这里的ptr1指向(uint8_t *)ptr1 +2,即ptr1之后的2个字节

4 个答案:

答案 0 :(得分:1)

首先写掩码

#define mask 0xFFFFFFFFFFFF 

ptr1中提取6个字节并存储它们

const uint64_t first_six = *ptr1 & mask;

ptr2中提取2个字节并存储它们

const uint16_t last_two = *ptr2 & 0xFFFFull;

最后,把它们放在一起

uint64_t value = (first_six << 16) | last_two;

在单个表达式中

uint64_t value = ( (*ptr1 & mask) << 16 ) | (*ptr2 & 0xFFFFull);
  

我还想知道在屏蔽期间字节顺序是否重要?

在这种情况下,字节顺序并不重要。

答案 1 :(得分:0)

我不太确定你在这里要做什么,你的问题有些模糊......但据我所知,我会尝试:

你的最后一行

libs

执行此操作:它提取* ptr1的前48位,并将结果乘以2 ^ 16。结果是一个包含* ptr1的中间32位的数字,移位到其​​前32位。然后从* ptr2中提取前16位,或者从第一个值中提取前16位。您的结果将在组合值的前32位内,* ptr2中的位直接与* ptr1中的位相关。你可能想做这样的事情:

value = (uint64_t)((*ptr1 & ~0x000000000000ffff)  << 16 | (*ptr2 & 0xffff000000000000));

将* ptr1的低48位与* ptr2的高16位组合,或

value = (uint64_t)((*ptr1  >> 16) | (*ptr2 & 0xffff000000000000));

将* ptr1的高48位与* ptr2的低48位组合,或者甚至

value = (uint64_t)((*ptr1 & ~0x000000000000ffff) | (*ptr2 & 0x000000000000ffff));

将* ptr1的前48位置于新值的底部,将* ptr2的前16位置于结果的前16位。

答案 2 :(得分:0)

(uint64_t)((*ptr1 & ~0x000000000000ffff)  << 16 | (*ptr2 & 0xffff000000000000));

一次采取表达式:

(*ptr1 & ~0x000000000000ffff)   

结果为12 34 56 78 9a bc 00 00

12 34 56 78 9a bc 00 00  << 16 

结果为56 78 9a bc 00 00 00 00

(*ptr2 & 0xffff000000000000)) 

结果为12 34 00 00 00 00 00 00

56 78 9a bc 00 00 00 00 | 12 23 00 00 00 00 00 00 

结果为?? ?? 9a bc 00 00 00 00

没有附加*ptr1的前6个字节和*ptr2的最后2个字节

我建议

(uint64_t)((*ptr1 & ~0x000000000000ffff)  | (*ptr2 & 0x000000000000ffff));

答案 3 :(得分:0)

OP错误地尝试从太窄的常量制作64位掩码。

在小于64位int/unsigned 0x000000000000ffff的计算机上,宽度为#34;小于64&#34;。在32位计算机上,~0x000000000000ffff - &gt; 0xffff0000而不是0xffffffffffff0000

的希望

追加LL将确保常量至少为64位。

实现&#34;形成一个var值,使得从ptr1获取6个字节,从ptr2获取2个字节&#34;

#define BYTES7TO2_MASK (0xffffffffffff0000)
#define BYTES1TO0_MASK (0xffff)
value = ((*ptr1 & BYTES7TO2_MASK) >> 16) || ((*ptr2 & BYTES1TO0_MASK) << (64-16));