uint16_t *decode(uint64_t instr) {
// decode instr (this is new to me lol)
uint16_t icode = (instr >> 48) & ((1 << 16) - 1);
uint16_t p1 = (instr >> 32) & ((1 << 16) - 1);
uint16_t p2 = (instr >> 16) & ((1 << 16) - 1);
uint16_t p3 = (instr >> 00) & ((1 << 16) - 1);
return (uint16_t[]){icode, p1, p2, p3};
}
我有这个测试它:
uint16_t *arr = decode(number);
for(int i = 0; i < 4; i++) {
printf("%d\n", arr[i]);
}
然而,无论number
是什么,这都会打印0次。我还没有解决问题的第一部分,如何首先对四个uint16_t进行编码。
答案 0 :(得分:1)
如何首先对四个uint16_t进行编码
这并不难。您所要做的就是将每个uint16_t
逐个加载到uint64_t
,然后返回uint64_t
:
uint64_t encode(uint16_t uints[]) {
uint64_t master = 0;
for (uint8_t index = 0; index <= 3; ++index) {
master <<= 16; // Shift master left by 16 bits to create space for the next uint16
master |= uints[index]; // Load uints[index] to the lower 16 bits of master
} // Do this four times
return master;
}
要以相反的顺序加载uint16_t
,只需将uint8_t index = 0; index <= 3; ++index
替换为uint8_t index = 3; index >= 0; --index
。
答案 1 :(得分:1)
您最好的选择是使用memcpy
。大多数现代编译器都会将其优化为必要的位移,等等。
uint64_t pack(const uint16_t arr[static 4]) {
uint64_t res;
memcpy(&res, arr, 8);
return res;
}
void unpack(uint64_t v, uint16_t arr[static 4]) {
memcpy(arr, &v, 8);
}
请注意,结果取决于字节序,适合在同一台机器上打包和解包。另请注意,我正在使用static
数组说明符来检查调用者是否传递了至少4个元素(当可以进行此类检查时);如果这给你的编译器带来麻烦,只需删除static
说明符。
答案 2 :(得分:0)
首先,你不能以你现在拥有它的方式从一个函数传回一个数组(这就是你得到0的原因),你需要通过指针或静态引用传递它。
但是,由于你正在处理2个已知的位宽,你可以使用一个掩码并将其移开:
out[0] = val & 0x000000000000FFFF; // 1st word
out[1] = (val & 0x00000000FFFF0000) >> 16; // 2nd word
out[2] = (val & 0x0000FFFF00000000) >> 32; // 3rd word
out[3] = (val & 0xFFFF000000000000) >> 48; // 4th word
你可以把它放在一个函数或宏中:
#define MACRO_DECODE(val, arr) arr[0]= val & 0x000000000000FFFF; \
arr[1] = (val & 0x00000000FFFF0000) >> 16; \
arr[2] = (val & 0x0000FFFF00000000) >> 32; \
arr[3] = (val & 0xFFFF000000000000) >> 48;
void decode(uint64_t val, uint16_t *out)
{
out[0] = val & 0x000000000000FFFF;
out[1] = (val & 0x00000000FFFF0000) >> 16;
out[2] = (val & 0x0000FFFF00000000) >> 32;
out[3] = (val & 0xFFFF000000000000) >> 48;
}
int main(int argc, char** argv)
{
int i;
uint16_t arr[] = { 0, 0, 0, 0} ;
for (i = 0; i < 4; ++i) {
printf("%#06x = %d\n", arr[i], arr[i]);
}
// as a function
decode(0xAAAABBBBCCCCDDDD, arr);
for (i = 0; i < 4; ++i) {
printf("%#06x = %d\n", arr[i], arr[i]);
}
// as a macro
MACRO_DECODE(0xDDDDCCCCBBBBAAAA, arr);
for (i = 0; i < 4; ++i) {
printf("%#06x = %d\n", arr[i], arr[i]);
}
return 0;
}
此外,您可以使用memcpy
:
int main(int argc, char** argv)
{
int i;
uint16_t arr[] = { 0, 0, 0, 0} ;
uint64_t src = 0xAAAABBBBCCCCDDDD;
for (i = 0; i < 4; ++i) {
printf("%#06x = %d\n", arr[i], arr[i]);
}
// memcpy
memcpy(arr, &src, sizeof(arr));
for (i = 0; i < 4; ++i) {
printf("%#06x = %d\n", arr[i], arr[i]);
}
return 0;
}
希望可以提供帮助。