Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何将四个16位uint编码为64位uint,然后再次解码?_C_Bit Manipulation - Fatal编程技术网

C 如何将四个16位uint编码为64位uint,然后再次解码?

C 如何将四个16位uint编码为64位uint,然后再次解码?,c,bit-manipulation,C,Bit Manipulation,我在以下人员的帮助下编写了此函数: uint16\u t*解码(uint64\u t指令){ //解码指令(这对我来说是新的lol) uint16\u t icode=(仪表>>48)和((1>32)和((1>16)和((1>00)和((1 首先,如何对四个uint16\t进行编码 这并不难。您所要做的就是将每个uint16\u t逐个加载到uint64\u t,然后返回该uint64\u t: uint64_t encode(uint16_t uints[]) { uint64_t m

我在以下人员的帮助下编写了此函数:

uint16\u t*解码(uint64\u t指令){
//解码指令(这对我来说是新的lol)
uint16\u t icode=(仪表>>48)和((1>32)和((1>16)和((1>00)和((1
首先,如何对四个uint16\t进行编码

这并不难。您所要做的就是将每个
uint16\u t
逐个加载到
uint64\u t
,然后返回该
uint64\u 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;
}
uint64\u t编码(uint16\u t单元[]){
uint64_t master=0;

对于(uint8_t index=0;index您的最佳选择实际上是使用
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);
}

请注意,结果依赖于endian,适用于在同一台机器上打包和解包。还要注意,我使用
static
数组说明符检查调用方是否至少传递了4个元素(如果可以进行此类检查);如果这给编译器带来了麻烦,只需删除
静态
说明符。

首先,不能按当前的方式从函数中传回数组(这就是为什么得到0的原因),需要通过指针或静态引用来传递它

但是,由于您处理的是两个已知的位宽度,因此可以使用掩码并将其移开:

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;
}

希望这能有所帮助。

你不能像那样以指针的形式返回数组。如果你真的想返回数组指针,数组必须用malloc动态分配。试着将数组作为函数参数并填充到函数中,而不是返回它。很酷,谢谢,函数的其余部分正确吗?另外,要小心。在这里,你的“00”是无害的,但是像“020”这样的东西不会被解释为20个十进制,而是20个八进制。
1关于这一点非常重要的问题:它是
index++
还是
++index
?我曾经听说post(inc | dec)rement操作符(inc | dec)记住他们正在处理的数字的副本,而不是实际的数字。在这种情况下没有区别(当作为单独的语句使用时,它们以相同的方式工作)。在这种情况下,即使在性能上也没有区别。任何体面的现代编译器都应该能够生成相同的(fast)在它们之间没有区别的最简单的情况下为它们进行汇编。这很好,但它不是
uint16\u t uints[]
而不是
uint16\u t[]uints
?@dorukayhan是否使用post与pre的问题是因为post返回的是一个通常不使用的副本,而这需要额外的步骤,因此有些人(我自己)请相信,除非您需要post或需要返回结果,否则只需使用pre.But+HolyBlackCat几乎适用于所有系统,但我仍然喜欢遵循这一规则(有时我不在正常系统上!)(而且我对我的代码有点强迫症).我现在没有访问编译器的权限..我明天会测试两个答案,它们看起来现在都能正常工作
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;
}
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;
}