Ci-dessous j'ai construit un petit exemple d'un code sur lequel je travaille qui utilise des champs de bits. Lors de la mise en œuvre de l'opérateur de comparaison, j'ai remarqué que cela ne fonctionnait pas comme prévu. Le problème étant que -1 ne semble pas être inférieur à 1.construisant des champs de bits signés
Après avoir réfléchi un instant, il me semble que quelque chose ne va pas dans le masquage du constructeur.
J'ai ajouté le "aValue & MAX_VALUE" là parce que sinon le compilateur donne un avertissement de conversion. Mais masquer d'abord avec MAX_VALUE, puis lancer un int32_t ne me donne pas le bon résultat.
Est-ce que quelqu'un sait comment je peux résoudre ce problème? Je semble obtenir le résultat escompté lorsque j'écris minusOne.v = -1;
dans la méthode main(). Mais je ne suis pas sûr comment je pourrais écrire cela dans le constructeur (sans obtenir l'avertissement de conversion).
#include <iostream>
#include <cstdint>
using namespace std;
struct int27_t
{
int32_t v:27;
constexpr static int32_t MIN_VALUE = -(1L << 26);
constexpr static int32_t MAX_VALUE = (1L << 26) - 1;
constexpr static int32_t MASK = 0x7FFFFFF;
int27_t() : v(0) {}
explicit int27_t(int32_t aValue) : v(static_cast<int32_t>(aValue & MAX_VALUE)) {}
friend bool operator<(const int27_t& aLhs, const int27_t& aRhs);
};
bool operator<(const int27_t& aLhs, const int27_t& aRhs)
{
return aLhs.v < aRhs.v;
}
int main()
{
int27_t minusOne{-1};
int27_t plusOne{1};
cout << "MAX_VALUE == " << int27_t::MAX_VALUE << " == 0x" << hex << int27_t::MAX_VALUE << dec << endl;
cout << "-1 == " << minusOne.v << " == 0x" << hex << minusOne.v << dec << endl;
cout << "-1 cast to int32_t: " << static_cast<int32_t>(minusOne.v) << " == 0x" << hex << static_cast<int32_t>(minusOne.v) << dec << endl;
cout << "-1 < 1 ? " << (minusOne < plusOne) << endl;
cout << endl;
}
sortie du programme
MAX_VALUE == 67108863 == 0x3ffffff
-1 == 67108863 == 0x3ffffff
-1 cast to int32_t: 67108863 == 0x3ffffff
-1 < 1 ? 0
Il n'y a vraiment aucune raison d'utiliser un champ de bits ici. Sur les plates-formes modernes, cette structure sera arrondie à 32 bits de toute façon. De plus, le masquage et [le complément à deux] (https://en.wikipedia.org/wiki/Two's_complement) ne sont pas compatibles de cette façon, le bit de signe sera arraché. – tadman
@tadman, je comprends le masquage avec des déchirures MAX_VALUE du bit de signe. Mais comment puis-je résoudre ce problème? Le masquage avec la valeur MASK entraîne un avertissement de conversion. – jeebee
Je pense que @kamajii a d'excellents conseils et je vous encourage à le suivre. – tadman