Битовая маскировка и битовые манипуляции с 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
Дайте мне знать, если эти примеры решат вашу проблему.