使用C进行位掩码和位操作

问题描述 投票:-1回答:2

我一直试图理解位操作如何与C和指针一起工作,但没有运气。这是我的问题。我在内存中有8个字节,需要提取前61位并打印。例如:0000 0000 ..... 0010 0111,我需要提取值32(忽略64位的最后3位。)这在C中是如何工作的?我只有一个指向8字节开头的指针。

uint_64_t* myPointer;  // already pointing to start of 8bytes

typedef struct Solve{
    uint64_t myBytes: 64; // set a field thats equal to 64 bits
}

struct Solve s1;

s1.myBytes = *myPointer>>3; //failed attempt

printf("Bytes are %" PRIu64 "\n", s1.myBytes); // just prints out 0 when should be 32
c bit-manipulation bit bitmask
2个回答
1
投票

如果您打算在清除3个低位的情况下打印64位值,请取值并使用除最低3位设置之外的位掩码执行逻辑AND:

uint64_t myvalue = 0x0123456789abcdefULL;
uint64_t masked_value = myvalue & 0xfffffffffffffff8ULL;

printf("Bytes are %" PRIx64 "\n", masked_value );

输出:

Bytes are 123456789abcde8

0
投票

您需要清除64位变量中的低位3位。既然你对结构字段值的操作感兴趣,我已经包含了这样的例子。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>

#define B(x) S_to_binary_(#x)

typedef struct solve{
    u_int64_t myBytes: 64; //  field that has 64 bits
}Solve;

static inline unsigned long long S_to_binary_(const char *s)
{
    unsigned long long i = 0;
    while (*s) {
        i <<= 1;
        i += *s++ - '0';
    }
    return i;
}

int main(void)
{
    u_int64_t mask = ~0; // This will give you 1111...1111
    mask = mask<<3;      // This will become   1111...1000

    Solve * myPointer;       

    Solve s1;                  // declare the structure s1
    s1.myBytes = B(100111);    // init the myBytes to 38 (decimal)

    printf("Initial value of s1.myBytes is: %lld\n", s1.myBytes);      

    myPointer = & s1;          //  cannot take address of bit-field 'myBytes' directly
    myPointer->myBytes = (myPointer->myBytes & mask);   // change the value of myBytes 

    printf("Now     value of s1.myBytes is: %lld\n\n", s1.myBytes);    // print new value

    // more testing 
    uint64_t myvalue1 =  0x0123456789abcdefULL;
    uint64_t myvalue  =  B(100111);  

    uint64_t masked_value1 = myvalue1 & mask; // This will clear low 3 bits
    uint64_t masked_value =  myvalue & mask;  // This will clear low 3 bits

    printf("Bytes are: %" PRIx64 "\n", masked_value1 );

    printf("Value is: %lld\n", masked_value );

    return 0;
}

输出:

Initial value of s1.myBytes is: 39
Now     value of s1.myBytes is: 32

Bytes are: 123456789abcde8
Value is: 32

如果这些例子可以解决您的问题,请告诉我。

© www.soinside.com 2019 - 2024. All rights reserved.