简体   繁体   English

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

[英]how to form a 64bit number using 2 pointers?

Suppose I have two pointers 假设我有两个指针

uint64_t* ptr1;
uint64_t* ptr2;

I have to form a var value such that 6 bytes are taken from ptr1 and 2 bytes from ptr2 and currently ptr1 has consumed its initial 2 bytes and now the remaining bytes left to be processed is 6 bytes. 我必须形成一个var值,使得从ptr1获取6个字节,从ptr2获取2个字节,并且当前ptr1已经消耗了它的初始2个字节,现在剩下要处理的剩余字节是6个字节。

I wrote something like this 我写了这样的东西

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

Ideally its the mask should be 0xffff000000000000, but it doesn't work.(For processing purposes). 理想情况下,它的掩码应为0xffff000000000000,但它不起作用。(用于处理目的)。 How should I proceed and what am I doing wrong here? 我该怎么办?我在这里做错了什么? According to me it should just be 据我说它应该是

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

EDIT: ptr1 here points to (uint8_t*)ptr1 +2, ie 2 bytes after ptr1 编辑:ptr1这里指向(uint8_t *)ptr1 +2,即ptr1后的2个字节

First write the mask 先写下面具

#define mask 0xFFFFFFFFFFFF 

Extract 6 bytes out of ptr1 and store them ptr1提取6个字节并存储它们

const uint64_t first_six = *ptr1 & mask;

Extract 2 bytes out of ptr2 and store them ptr2提取2个字节并存储它们

const uint16_t last_two = *ptr2 & 0xFFFFull;

Finally, put them together 最后,把它们放在一起

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

In a single expression 在单个表达式中

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

I also wanted to know if endianness matters during masking? 我还想知道在屏蔽期间字节顺序是否重要?

Endianness has no importance in this case. 在这种情况下,字节顺序并不重要。

I'm not quite sure what you are trying to do here, your question is somewhat vague... but I'll try, as far as I understand: 我不太确定你在这里要做什么,你的问题有些模糊......但据我所知,我会尝试:

Your last line 你的最后一行

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

does this: it extracts the top 48 bits of *ptr1, and multiplies the result by 2^16. 这样做:它提取* ptr1的前48位,并将结果乘以2 ^ 16。 The result is a number that contains the middle 32 bits of *ptr1, shifted to its top 32 bits. 结果是一个包含* ptr1的中间32位的数字,移位到其​​前32位。 Then you extract the top 16 bits from *ptr2 and or that to this first value. 然后从* ptr2中提取前16位,或者从第一个值中提取前16位。 Your result will be within the top 32 bits of the combined value, with bits from *ptr2 directly being or'ed with bits from *ptr1. 您的结果将在组合值的前32位内,* ptr2中的位直接与* ptr1中的位相关。 You probably mean to do something like this: 你可能意味着做这样的事情:

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

which would combine the low 48 bits of *ptr1 with the high 16 bits of *ptr2, or 它将* ptr1的低48位与* ptr2的高16位组合,或

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

which combines the high 48 bits of *ptr1 with the low 48 bits of *ptr2, or maybe even 它将* ptr1的高48位与* ptr2的低48位组合,或者甚至可以组合

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

which would place the top 48 bits of *ptr1 at the bottom of the new value, and the bottom 16 bits of *ptr2 in the top 16 bits of the result. 这将把* ptr1的前48位置于新值的底部,将* ptr2的前16位置于结果的前16位。

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

Taken an expression at a time: 一次表达一个表达式:

(*ptr1 & ~0x000000000000ffff)   

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

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

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

(*ptr2 & 0xffff000000000000)) 

results in 12 34 00 00 00 00 00 00 结果为12 34 00 00 00 00 00 00

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

results in ?? ?? 9a bc 00 00 00 00 结果?? ?? 9a bc 00 00 00 00 ?? ?? 9a bc 00 00 00 00

which is not appending the first 6 bytes of *ptr1 with the last 2 bytes of *ptr2 未附加的前6个字节的*ptr1与最后2个字节的*ptr2

I suggest 我建议

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

OP is incorrectly attempting to make a 64-bit mask from a too narrow constant. OP错误地尝试从太窄的常量制作64位掩码。

On a machine with less than 64-bit int/unsigned 0x000000000000ffff is a constant of width "less-than 64". 在小于64位的机器上int/unsigned 0x000000000000ffff是宽度“小于64”的常量。 On a 32-bit machine, ~0x000000000000ffff --> 0xffff0000 and not the hoped for 0xffffffffffff0000 在一台32位机器上, ~0x000000000000ffff - > 0xffff0000而不是希望的0xffffffffffff0000

Appending LL will insure the constant is at least 64-bit. 附加LL将确保常量至少为64位。

To implement "form a var value such that 6 bytes are taken from ptr1 and 2 bytes from ptr2" 实现“形成一个var值,使得从ptr1获取6个字节,从ptr2获取2个字节”

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM