28 votes

Est static_cast <T> (-1) la bonne façon de générer des données tout-un-bit sans limites numériques?

J'écris du code C ++ dans un environnement dans lequel je n'ai pas accès à la bibliothèque standard C ++, en particulier pas à std::numeric_limits . Supposons que je veuille implémenter

 template <typename T> constexpr T all_ones( /* ... */ )
 

En me concentrant sur les types intégraux non signés, que dois-je y mettre? Plus précisément, est-ce que static_cast<T>(-1) assez bon? (D'autres types que je pourrais traiter comme un tableau de caractères non signés en fonction de leur taille, je suppose.)

32voto

Leandros Points 5916

Utilisez le bitwise NOT opérateur ~ en 0 .

 T allOnes = ~(T)0;
 

Un static_cast<T>(-1) suppose un complément à deux, qui n'est pas portable. Si vous n'êtes préoccupé que par les types non signés, la réponse de hvd est la voie à suivre.

Exemple de travail: https://ideone.com/iV28u0

8voto

OmnipotentEntity Points 7083

Cette façon désarmante directe.

 T allOnes;
memset(&allOnes, ~0, sizeof(T));
 

7voto

DOUGLAS O. MOEN Points 837

En me concentrant sur les types intégraux non signés, que dois-je y mettre? Plus précisément, static_cast (-1) est assez bon

Oui, c'est assez bon.

Mais je préfère une valeur hexadécimale car mon arrière-plan est des systèmes embarqués, et j'ai toujours dû connaître la taille de (T).

Même dans les systèmes de bureau, nous connaissons les tailles des T suivants:

 uint8_t  allones8  = 0xff;
uint16_t allones16 = 0xffff;
uint32_t allones32 = 0xffffffff;
uint64_t allones64 = 0xffffffffffffffff;
 

4voto

Lưu Vĩnh Phúc Points 3183
static_cast<T>(-1ull)

serait plus correct et fonctionne dans n'importe quel signé format indépendamment du 1er complément, complément de 2 ou signe de grandeur.

Parce que unaire moins d'un entier non signé valeur est définie comme

Le négatif d'un unsigned quantité est calculée en soustrayant la valeur de 2^n, où n est le nombre de bits dans le promu opérande."

Par conséquent, -1u retournera toujours la une de tous les bits de données en unsigned int. ll suffixe est de le faire fonctionner pour tous les types plus étroit que l' unsigned long long. Il n'y a pas étendu les types integer (encore) en C++, donc cela devrait être bon

Toutefois, un plus concise solution serait

static_cast<T>(~0ull)

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