将6个字节的数组复制到long long整数变量 [英] Copy 6 byte array to long long integer variable
问题描述
我从内存中读取了一个6字节的unsigned char
数组.
字节序是这里的大字节序(Big Endian).
现在,我想将存储在数组中的值分配给一个整数变量.我认为这必须是long long
,因为它必须包含最多6个字节.
I have read from memory a 6 byte unsigned char
array.
The endianess is Big Endian here.
Now I want to assign the value that is stored in the array to an integer variable. I assume this has to be long long
since it must contain up to 6 bytes.
目前,我以这种方式进行分配:
At the moment I am assigning it this way:
unsigned char aFoo[6];
long long nBar;
// read values to aFoo[]...
// aFoo[0]: 0x00
// aFoo[1]: 0x00
// aFoo[2]: 0x00
// aFoo[3]: 0x00
// aFoo[4]: 0x26
// aFoo[5]: 0x8e
nBar = (aFoo[0] << 64) + (aFoo[1] << 32) +(aFoo[2] << 24) + (aFoo[3] << 16) + (aFoo[4] << 8) + (aFoo[5]);
memcpy方法会很整洁,但是当我这样做时
A memcpy approach would be neat, but when I do this
memcpy(&nBar, &aFoo, 6);
这6个字节从头开始复制到long long
,因此在末尾具有填充零.
有没有比我分配工作更好的方法了?
the 6 bytes are being copied to the long long
from the start and thus have padding zeros at the end.
Is there a better way than my assignment with the shifting?
推荐答案
您要完成的工作称为反序列化或反编组.
What you want to accomplish is called de-serialisation or de-marshalling.
对于如此宽的值,使用循环是个好主意,除非您确实需要最大值.速度,并且编译器无法向量化循环:
For values that wide, using a loop is a good idea, unless you really need the max. speed and your compiler does not vectorise loops:
uint8_t array[6];
...
uint64_t value = 0;
uint8_t *p = array;
for ( int i = (sizeof(array) - 1) * 8 ; i >= 0 ; i -= 8 )
value |= (uint64_t)*p++ << i;
//左对齐 值<< = 64-(sizeof(array)* 8);
// left-align value <<= 64 - (sizeof(array) * 8);
请注意使用stdint.h
类型和sizeof(uint8_t) cannot differ from
1`.仅保证这些具有预期的位宽.移位值时也请使用无符号整数.右移某些值是实现定义的,而左移会调用未定义的行为.
Note using stdint.h
types and sizeof(uint8_t) cannot differ from
1`. Only these are guaranteed to have the expected bit-widths. Also use unsigned integers when shifting values. Right shifting certain values is implementation defined, while left shifting invokes undefined behaviour.
如果 f 您需要一个带符号的值,只需
Iff you need a signed value, just
int64_t final_value = (int64_t)value;
移位后.这仍然是实现定义的,但是所有现代实现(可能是较旧的实现)仅复制该值而无需修改.现代的编译器可能会对此进行优化,因此不会有任何损失.
after the shifting. This is still implementation defined, but all modern implementations (and likely the older) just copy the value without modifications. A modern compiler likely will optimize this, so there is no penalty.
当然可以移动声明.我只是将它们放在用于完整性的地方.
The declarations can be moved, of course. I just put them before where they are used for completeness.
这篇关于将6个字节的数组复制到long long整数变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!