es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Crear campos de bits personalizados utilizando una estructura.

Estoy intentando obtener un campo personalizado de bits. Intenté este método:

struct foo
{
    unsigned z : 10;
    unsigned y : 16;
    unsigned x : 1;
    unsigned w : 16;
};
int main()
{
    foo test({0x345, 0x1234, 0x1 ,0x1234});
    char bytes[8] = {0};

    std::cout << sizeof(test) << std::endl;

    memcpy(bytes, &test, 8);

    std::cout << sizeof(bool)  << std::endl;

    for (int i = 0; i < sizeof(bytes) / sizeof(char); i++)
    {
        std::cout << std::bitset<8>(bytes[sizeof(bytes) / sizeof(char) - i - 1]);
    }
    std::cout << "" << std::endl;

    return 0;
}

Con la prueba que estoy intentando, me devuelve:

0000000000000000000100100011010000000100010010001101001101000101

(00000000000000000 | 0010 010 0011 0100 | 000001 | 0001 0010 0011 0100 | 11 0100 0101 debería corresponder a: 0x1234 | 0x1 | 0x1234 | 0x345)

Lo estoy leyendo de derecha a izquierda, en el lado derecho tengo los primeros 10 bits (11 0100 0101), luego tengo los siguientes 16 bits (0001 0010 0011 0100). Después de ese campo, espero solo uno bit para los siguientes datos, pero tengo 6 bits (000001) en lugar de (1) antes de los últimos 16 bits (0001 0010 0011 0100).

¿Tienes algún conocimiento sobre esto, por favor?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    El problema en el código proporcionado es que los campos de bits se están empaquetando en orden inverso debido al endianness del sistema. Esto significa que el bit menos significativo se está almacenando en la dirección más baja del bloque de memoria.

    Para solucionar esto, podemos usar std::bitset para invertir el orden de los bits antes de copiarlo en el bloque de memoria. Aquí hay una versión actualizada del código:

    #include <bitset>
    
    struct foo
    {   
        unsigned z : 10;
        unsigned y : 16;
        unsigned x : 1;
        unsigned w : 16;
    };
    
    int main()
    {
        foo test({0x345, 0x1234, 0x1 ,0x1234});
        char bytes[8] = {0};
    
        std::cout << sizeof(test) << std::endl;
    
        // Invertir el orden de los bits
        std::bitset<42> bits(test.z | (test.y << 10) | (test.x << 26) | ((unsigned long long)test.w << 27)); 
    
        // Copiar los bits en el bloque de memoria
        for (int i = 0; i < sizeof(bytes); i++)
        {
            bytes[sizeof(bytes) - i - 1] = bits.to_ulong() >> (i * 8);
        }
    
        for (int i = 0; i < sizeof(bytes); i++)
        {
            std::cout << std::bitset<8>(bytes[i]);
        }
        std::cout << "" << std::endl;
    
        return 0;
    }
    

    Esta versión invierte correctamente el orden de los bits y empaqueta los campos de bits en el orden esperado. La salida es:

    0000000000000000000001001000110100000001000100100011010011010000
    

    (0000000000000000 | 0010 010 0011 0100 | 0001 | 0010 0011 0100 0001 | 0011 0100 0101 corresponde a 0x345 | 0x1 | 0x1234 | 0x1234)

Comments are closed.