0
votes

Exporter le champ de bits vers un tableau

J'ai déclaré ce champ de bit. Ce que j'essaie de faire est d'obtenir la valeur entière du bitfield en binaire et de le convertir en une matrice afin que je puisse utiliser l'index et adresser toutes les valeurs de «1».

union{
    struct shape{
        uint8_t p0 : 1;
        uint8_t p1 : 1;
        uint8_t p2 : 1;
        uint8_t p3 : 1;
        uint8_t p4 : 1;
        uint8_t p5 : 1;
        uint8_t p6 : 1;
        uint8_t p7 : 1;
    };
    uint8_t row;
}rows[8*2+4];


5 commentaires

veuillez choisir une langue. En particulier, les union sont différents en C et C ++


@skoya Voulez-vous quelque chose comme lignes [0] [3] ?


avez-vous essayé dynamic_bitset de boost? (voir boost.org/doc/libs/1_72_0/libs/ dynamic_bitset /… )


Hey, qu'est-ce que j'essaie de faire est d'exporter le bitfield pour avoir un tableau comme UINT8_T TAB = {0,1,1,0,0,1,1};


C'est impossible sans savoir quel bit est le MSB et la disposition de la mémoire du champ de bits. Vous devez nous indiquer ces parties, car elles sont spécifiques à votre compilateur. Par exemple, row n'a pas besoin de refléter les bits de valeur de votre champ de bits, il pourrait aussi bien refléter un octet de remplissage.


4 Réponses :


0
votes

Au lieu d'utiliser des champs de bits, utilisez juste un tableau de uint8_t et accédez à chaque bit en utilisant des décalages et des masques. Il n'y a en fait aucun autre moyen d'accéder aux bits par index en C standard (sans compter les implémentations de bibliothèques).

uint8_t data[SIZE];
...
data[bitIndex >> 3] |= 1 << (bitIndex & 7);  // set bit at bitIndex
data[bitIndex >> 3] &= ~(1 << (bitIndex & 7); // clear bit at bitIndex
bitValue = !!(data[bitIndex >> 3] & (1 << bitIndex & 7)); // read bit at bitIndex

L'utilisation de types plus grands (16, 32, 64) peut être plus efficace mais nécessite changé les équipes et les masques (par exemple, 4 et 15 pour uint16_t).


4 commentaires

Les opérations bits du bitwise sont le seul moyen.


@Fareanor C'est évidemment par index, d'où 1 << bitIndex . Utiliser l'opérateur [] pour le plaisir ne remplit aucun but.


@Lundin Eh bien, j'ai mal lu la réponse, mon commentaire n'était pas pertinent alors (je l'ai supprimé).


Mais vous m'avez fait clarifier ce point, alors j'ai modifié mon commentaire en conséquence, alors merci pour vos commentaires.



0
votes

Si vous souhaitez simplement exporter vos champs de bits, c'est possible avec la conversion définie par l'utilisateur de votre union vers std :: array . Notez que, il est juste possible de lire des bits (non définis).

#include <cstdint>
#include <iostream>
#include <bitset>

int main()
{
    uint8_t data_comes_from_somewhere = 0b01001001;
    std::string data_comes_from_somewhere_as_string { "11101001" };
    std::bitset<8> bitfields { data_comes_from_somewhere };
    std::bitset<8> bitfields_2 { data_comes_from_somewhere_as_string };

    std::cout << bitfields << std::endl;
    std::cout << bitfields_2 << std::endl;

    // Set leftmost bit
    bitfields[ 7 ] = 1;
    int leftmost_bit = bitfields[ 7 ];

    std::cout << bitfields << std::endl;
    std::cout << leftmost_bit << std::endl;
}

Mais je ne suggère pas d'utiliser cette méthode. Pour autant que je sache, vous lisez une valeur de quelque part et vous voulez accéder / manipuler les bits comme un tableau. std :: bitset est une bonne option pour ce faire.

Implémentation possible comme celle-ci:

union{
    struct shape{
        uint8_t p0 : 1;
        uint8_t p1 : 1;
        uint8_t p2 : 1;
        uint8_t p3 : 1;
        uint8_t p4 : 1;
        uint8_t p5 : 1;
        uint8_t p6 : 1;
        uint8_t p7 : 1;
    } bits;

    operator std::array<bool , 8>(){
        std::array<bool , 8> exported_array;
        exported_array[ 0 ] = bits.p0;
        exported_array[ 1 ] = bits.p1;
        exported_array[ 2 ] = bits.p2;
        exported_array[ 3 ] = bits.p3;
        exported_array[ 4 ] = bits.p4;
        exported_array[ 5 ] = bits.p5;
        exported_array[ 6 ] = bits.p6;
        exported_array[ 7 ] = bits.p7;

        return exported_array;
    }

    uint8_t row;
} rows[8*2+4];

int main()
{
    rows[0].row = static_cast<uint8_t>( 643211 );
    std::array< bool , 8 > data = rows[ 0 ];

    for ( auto bit : data )
        std::cout << static_cast<int>( bit );
}


2 commentaires

Vous faites beaucoup d'hypothèses sur l'ordre des bits et des octets qui ne sont pas spécifiées par la norme.


@Lundin S'il lisait la valeur sous forme de chaîne, ce ne serait pas un problème. OP ne demande pas non plus sa portabilité.



1
votes

Si vous êtes, en fait, à partir d'un uint8_t , alors vous n'avez pas besoin ou ne voulez pas jouer avec les champs de bits ...

... en supposant (a) Little-Endian et (b) que vous pouvez écrire un uint64_t non aligné :

void explode_byte(uint8_t r[8], uint8_t b)
{
  uint64_t x ;

  x  = b ;
  x |= x << (32 - 4) ;
  x |= x << (16 - 2) ;
  x |= x << ( 8 - 1) ;

  *(uint64_t*)r = x & (uint64_t)0x0101010101010101 ;
}

Voir "Hacker's Delight" par Henry S. Warren :-)


Mais, si vous commencez par les champs de bits, alors vous avez un problème tout à fait différent: vous ne pouvez vraiment pas faire d'hypothèses sur la façon dont les champs de bits sont stockés - tout ce que vous pouvez faire est de lire / écrire des champs individuels. Vous n'avez donc pas d'autre choix que de copier chaque champ de bits dans son octet respectif ... comme indiqué dans d'autres réponses.


1 commentaires

Notez qu'en C ++ le résultat de (uint64_t *) r est indéterminé si l'alignement de r est différent de l'alignement de uint64_t . (Je n'ai pas vérifié la norme C)



0
votes
#ifndef __BIN_8BITS__
#define __BIN_8BITS__

#define b00000000 0x0000
#define b00000001 0x0001
#define b00000010 0x0002
#define b00000011 0x0003
#define b00000100 0x0004
#define b00000101 0x0005
#define b00000110 0x0006
#define b00000111 0x0007
#define b00001000 0x0008
#define b00001001 0x0009
#define b00001010 0x000A
#define b00001011 0x000B
#define b00001100 0x000C
#define b00001101 0x000D
#define b00001110 0x000E
#define b00001111 0x000F
#define b00010000 0x0010
#define b00010001 0x0011
#define b00010010 0x0012
#define b00010011 0x0013
#define b00010100 0x0014
#define b00010101 0x0015
#define b00010110 0x0016
#define b00010111 0x0017
#define b00011000 0x0018
#define b00011001 0x0019
#define b00011010 0x001A
#define b00011011 0x001B
#define b00011100 0x001C
#define b00011101 0x001D
#define b00011110 0x001E
#define b00011111 0x001F
#define b00100000 0x0020
#define b00100001 0x0021
#define b00100010 0x0022
#define b00100011 0x0023
#define b00100100 0x0024
#define b00100101 0x0025
#define b00100110 0x0026
#define b00100111 0x0027
#define b00101000 0x0028
#define b00101001 0x0029
#define b00101010 0x002A
#define b00101011 0x002B
#define b00101100 0x002C
#define b00101101 0x002D
#define b00101110 0x002E
#define b00101111 0x002F
#define b00110000 0x0030
#define b00110001 0x0031
#define b00110010 0x0032
#define b00110011 0x0033
#define b00110100 0x0034
#define b00110101 0x0035
#define b00110110 0x0036
#define b00110111 0x0037
#define b00111000 0x0038
#define b00111001 0x0039
#define b00111010 0x003A
#define b00111011 0x003B
#define b00111100 0x003C
#define b00111101 0x003D
#define b00111110 0x003E
#define b00111111 0x003F
#define b01000000 0x0040
#define b01000001 0x0041
#define b01000010 0x0042
#define b01000011 0x0043
#define b01000100 0x0044
#define b01000101 0x0045
#define b01000110 0x0046
#define b01000111 0x0047
#define b01001000 0x0048
#define b01001001 0x0049
#define b01001010 0x004A
#define b01001011 0x004B
#define b01001100 0x004C
#define b01001101 0x004D
#define b01001110 0x004E
#define b01001111 0x004F
#define b01010000 0x0050
#define b01010001 0x0051
#define b01010010 0x0052
#define b01010011 0x0053
#define b01010100 0x0054
#define b01010101 0x0055
#define b01010110 0x0056
#define b01010111 0x0057
#define b01011000 0x0058
#define b01011001 0x0059
#define b01011010 0x005A
#define b01011011 0x005B
#define b01011100 0x005C
#define b01011101 0x005D
#define b01011110 0x005E
#define b01011111 0x005F
#define b01100000 0x0060
#define b01100001 0x0061
#define b01100010 0x0062
#define b01100011 0x0063
#define b01100100 0x0064
#define b01100101 0x0065
#define b01100110 0x0066
#define b01100111 0x0067
#define b01101000 0x0068
#define b01101001 0x0069
#define b01101010 0x006A
#define b01101011 0x006B
#define b01101100 0x006C
#define b01101101 0x006D
#define b01101110 0x006E
#define b01101111 0x006F
#define b01110000 0x0070
#define b01110001 0x0071
#define b01110010 0x0072
#define b01110011 0x0073
#define b01110100 0x0074
#define b01110101 0x0075
#define b01110110 0x0076
#define b01110111 0x0077
#define b01111000 0x0078
#define b01111001 0x0079
#define b01111010 0x007A
#define b01111011 0x007B
#define b01111100 0x007C
#define b01111101 0x007D
#define b01111110 0x007E
#define b01111111 0x007F
#define b10000000 0x0080
#define b10000001 0x0081
#define b10000010 0x0082
#define b10000011 0x0083
#define b10000100 0x0084
#define b10000101 0x0085
#define b10000110 0x0086
#define b10000111 0x0087
#define b10001000 0x0088
#define b10001001 0x0089
#define b10001010 0x008A
#define b10001011 0x008B
#define b10001100 0x008C
#define b10001101 0x008D
#define b10001110 0x008E
#define b10001111 0x008F
#define b10010000 0x0090
#define b10010001 0x0091
#define b10010010 0x0092
#define b10010011 0x0093
#define b10010100 0x0094
#define b10010101 0x0095
#define b10010110 0x0096
#define b10010111 0x0097
#define b10011000 0x0098
#define b10011001 0x0099
#define b10011010 0x009A
#define b10011011 0x009B
#define b10011100 0x009C
#define b10011101 0x009D
#define b10011110 0x009E
#define b10011111 0x009F
#define b10100000 0x00A0
#define b10100001 0x00A1
#define b10100010 0x00A2
#define b10100011 0x00A3
#define b10100100 0x00A4
#define b10100101 0x00A5
#define b10100110 0x00A6
#define b10100111 0x00A7
#define b10101000 0x00A8
#define b10101001 0x00A9
#define b10101010 0x00AA
#define b10101011 0x00AB
#define b10101100 0x00AC
#define b10101101 0x00AD
#define b10101110 0x00AE
#define b10101111 0x00AF
#define b10110000 0x00B0
#define b10110001 0x00B1
#define b10110010 0x00B2
#define b10110011 0x00B3
#define b10110100 0x00B4
#define b10110101 0x00B5
#define b10110110 0x00B6
#define b10110111 0x00B7
#define b10111000 0x00B8
#define b10111001 0x00B9
#define b10111010 0x00BA
#define b10111011 0x00BB
#define b10111100 0x00BC
#define b10111101 0x00BD
#define b10111110 0x00BE
#define b10111111 0x00BF
#define b11000000 0x00C0
#define b11000001 0x00C1
#define b11000010 0x00C2
#define b11000011 0x00C3
#define b11000100 0x00C4
#define b11000101 0x00C5
#define b11000110 0x00C6
#define b11000111 0x00C7
#define b11001000 0x00C8
#define b11001001 0x00C9
#define b11001010 0x00CA
#define b11001011 0x00CB
#define b11001100 0x00CC
#define b11001101 0x00CD
#define b11001110 0x00CE
#define b11001111 0x00CF
#define b11010000 0x00D0
#define b11010001 0x00D1
#define b11010010 0x00D2
#define b11010011 0x00D3
#define b11010100 0x00D4
#define b11010101 0x00D5
#define b11010110 0x00D6
#define b11010111 0x00D7
#define b11011000 0x00D8
#define b11011001 0x00D9
#define b11011010 0x00DA
#define b11011011 0x00DB
#define b11011100 0x00DC
#define b11011101 0x00DD
#define b11011110 0x00DE
#define b11011111 0x00DF
#define b11100000 0x00E0
#define b11100001 0x00E1
#define b11100010 0x00E2
#define b11100011 0x00E3
#define b11100100 0x00E4
#define b11100101 0x00E5
#define b11100110 0x00E6
#define b11100111 0x00E7
#define b11101000 0x00E8
#define b11101001 0x00E9
#define b11101010 0x00EA
#define b11101011 0x00EB
#define b11101100 0x00EC
#define b11101101 0x00ED
#define b11101110 0x00EE
#define b11101111 0x00EF
#define b11110000 0x00F0
#define b11110001 0x00F1
#define b11110010 0x00F2
#define b11110011 0x00F3
#define b11110100 0x00F4
#define b11110101 0x00F5
#define b11110110 0x00F6
#define b11110111 0x00F7
#define b11111000 0x00F8
#define b11111001 0x00F9
#define b11111010 0x00FA
#define b11111011 0x00FB
#define b11111100 0x00FC
#define b11111101 0x00FD
#define b11111110 0x00FE
#define b11111111 0x00FF

#endif

0 commentaires