2 votes

Comment utiliser un bitflag sur un unsigned int afin d'y stocker une valeur bool supplémentaire ?

J'utilise des ints non signés pour représenter un certain nombre d'avions dans un jeu. Chaque avion a deux états, en vol et au sol. J'aimerais stocker cet état avec le numéro de l'avion. Quelle est la "meilleure" façon d'y parvenir ? Je pourrais utiliser std::maps avec les avions et leur état, mais cela me semble excessif et lent. Pourrait-on utiliser des drapeaux ? L'assignation et le test du test doivent être rapides.

Pseudo-code :

unsigned int Boing = 777;

if( Boing is flying)
 set some bit;

is Boing flying? (how to check for the current state)

Toute indication sur une solution simple et rapide est appréciée !

2voto

Johnny Mopp Points 6485

Une solution simple consisterait à rendre le nombre négatif s'il ne s'agit pas d'un vol.

2voto

moonshadow Points 28302
struct Stuff
{
  unsigned int Boing: 31;
  unsigned int isFlying: 1;
};

.
.
.

Stuff myStuff;
myStuff.Boing = 777;
myStuff.isFlying = false;

En savoir plus sur les champs de bits

2voto

Oli Charlesworth Points 148744

La méthode la plus rapide et la plus propre consiste probablement à éviter les champs de bits et à définir simplement une structure :

struct Plane
{
    bool isFlying;
    unsigned int number;
}

...

std::vector<Plane> planes;
Plane p;
p.isFlying = true;
p.number = 777;
planes.push_back(p);

Cette méthode utilisera plus de mémoire que d'essayer d'insérer le drapeau dans le même mot, mais elle nécessitera moins de travail pour obtenir/définir les champs. À moins que vous ne disposiez de peu de mémoire, je vous recommande vivement d'éviter d'essayer de tout comprimer.

Vous pouvez même envisager d'utiliser un enum plutôt qu'un bool pour l'État.

1voto

Jerry Coffin Points 237758

En supposant que vous n'utilisiez jamais toute la gamme des valeurs disponibles dans votre unsigned int (une possibilité raisonnable, mais loin d'être absolument certaine), vous pourriez simplement limiter la gamme à un bit de moins que ce que contient un unsigned in, et utiliser ensuite le bit le plus significatif pour stocker l'état "volant". Dans ce cas, vous pourriez faire quelque chose comme :

// This theoretically isn't required to work, but will for most reasonable machines.
unsigned flying_bit = 1 << (CHAR_BITS * sizeof(unsigned));

void take_off(unsigned &plane) {
    plane |= flying_bit;
}

void land(unsigned &plane) { 
    plane &= flying_bit;
}

bool is_flying(unsigned const &plane) { 
    return plane & flying_bit != 0;
}

Une autre possibilité serait d'utiliser de véritables champs de bits :

struct plane { 
    uint32_t model: 31;
    uint32_t flying: 1;
};

Dans ce cas, il suffit d'attribuer des valeurs directement, comme par exemple :

plane myplane = {777, 0};

myplane.flying = 1; // take off

myplane.flying = 0; // land

1voto

epic fail guy Points 41

Pourquoi ne pas signer les nombres entiers ? Les valeurs positives sont volantes, les négatives ne le sont pas, et zéro n'est pas valide.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X