Битовая маскировка и битовые манипуляции с C

Я пытался понять, как битовые операции работают с C и указателями, но не повезло. Здесь моя проблема. У меня в памяти 8 байтов, и мне нужно извлечь первые 61 бит и распечатать. Например: 0000 0000..... 0010 0111, мне нужно извлечь значение 32 (игнорируя последние 3 бита из 64 бит). Как это работает в 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

2 ответа

Если вы хотите напечатать 64-битное значение с очищенными 3 младшими битами, возьмите это значение и выполните логическое И с битовой маской, в которой установлены все, кроме самых младших 3 битов:

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

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

Выход:

Bytes are 123456789abcde8

Вам нужно очистить младшие 3 бита в вашей 64-битной переменной. Так как вас интересовало манипулирование значением поля структуры, я включил такой пример.

#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

Дайте мне знать, если эти примеры решат вашу проблему.

Другие вопросы по тегам