在64位无符号变量中更新具有不同值的每个块(4位)?

时间:2016-01-20 08:30:12

标签: c

我有一个变量unsigned __int64 text=0x0;,我需要用不同的值更新每个4位。

text = b64b63 ... b3b2b1b0 我有一个循环,循环内部必须是这样的:

for(i=0;i<16;i++)
 {
     b3b2b1b0=a[0]
     b7b6b5b4=a[1]
     b11b10b9b8=a[2]
     ..
     .. 
     ..
 }

我试过这个,但没有工作

unsigned __int64 temp=0x0;
unsigned __int64 index=0x0;
for(i=0;i<16;i++)
 {
    index = (text>>(i*4))&0x0F;
    temp = a[index];
    text = text | temp<<(i*4);
 }

非常感谢你

4 个答案:

答案 0 :(得分:2)

您可以使用bitshifting和bitwise-OR来执行此操作。假设a[n]值都在0到15之间,还有unsigned __int64 s:

unsigned __int64 text=0x0;

text = a[0] |
       a[1] << 4 |
       a[2] << 8 |
       etc....;

如果您不信任a[n]值,请在移位前使用(a[n] & 0xF)清除除四个最低有效位之外的所有位。如果a[n]不是unsigned __int64,请在转移之前将其投射。

答案 1 :(得分:1)

您可以使用位字段:

typedef struct {
    int n0 : 4;
    int n1 : 4;
    int n2 : 4;
    int n3 : 4;
    int n4 : 4;
    int n5 : 4;
    int n6 : 4;
    int n7 : 4;
    int n8 : 4;
    int n9 : 4;
    int n10 : 4;
    int n11 : 4;
    int n12 : 4;
    int n13 : 4;
    int n14 : 4;
    int n15 : 4;
} S64;

typedef union {
    uint64_t i;
    S64 b;
} U64;

注意:如果您需要对64位值中的4位字段进行特定排序,则可能需要注意目标平台的字节顺序。

答案 2 :(得分:1)

如果您必须使用循环,您可以执行类似

的操作
uint64_t text = 0;
for (int i = 15; i >= 0; --i)
{
    text <<= 4;
    text |= a[i] & 0x0f;  // Masking in case a[i] have more than the lowest four bits set
}

答案 3 :(得分:1)

尝试以下代码。我试图将0x01,0x02 ...... 0x0f复制到16个不同的半字节中。代码提取值并将它们与OR运算结合使用。

#define NIBBLES   16      /* 64-bit has 16 nibbles */
#define MASK      0x0FLLU  


int main()
{
    unsigned int val[NIBBLES] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                                 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};

    long long unsigned int num = 0, tmp;
    int i, shift = 0;

    for (i = 0; i < NIBBLES; i++) { 
        tmp = (val[i] & MASK) << shift;
        num = num | tmp;
        shift = shift + 4;
    }
    printf ("0x%llx\n", num);

}

输出:0xfedcba9876543210