Comment puis-je utiliser les opérateurs au niveau du bit sur un “double” sur le C++?
M'a demandé d'obtenir le binaire interne de la représentation de différents types en C. Mon programme fonctionne très bien avec "int", mais je voudrais l'utiliser avec "double" et "float". Mon code ressemble à ceci:
template <typename T>
string findBin(T x) {
string binary;
for(int i = 4096 ; i >= 1; i/=2) {
if((x & i) != 0) binary += "1";
else binary += "0";
}
return binary;
}
Le programme ne parvient pas quand j'essaie d'instancier le modèle à l'aide d'un "double" ou un "float".
Ce que la sortie ne vous attendez lors de l'utilisation d'un lit double et/ou variable?
Rien si le bit est à 1 et à 0 si le bit est à zéro.
Juste quelque chose que je pensais que vous pourriez trouver intéressant: certains systèmes (esp. Linux) ont un ieee754.h-tête avec les syndicats
Rien si le bit est à 1 et à 0 si le bit est à zéro.
Juste quelque chose que je pensais que vous pourriez trouver intéressant: certains systèmes (esp. Linux) ont un ieee754.h-tête avec les syndicats
ieee754_float
et ieee754_double
qui définissent (endian sûr) bitfields pour la lecture de l'exposant mantisse, signe bits (négatif), pas-un-nombre de bits etc.OriginalL'auteur Juan Pablo Santos | 2011-01-20
Vous devez vous connecter pour publier un commentaire.
Succinctement, vous ne le font pas.
Les opérateurs au niveau du bit ne font pas de sens lorsqu'il est appliqué à
double
oufloat
, et le standard dit que les opérateurs au niveau du bit (~
,&
,|
,^
,>>
,<<
, et l'affectation des variantes) n'acceptent pasdouble
oufloat
opérandes.Les deux
double
etfloat
avoir 3 sections - un bit de signe, l'exposant et la mantisse. Supposons pour un instant que vous pourraient changer d'unedouble
droit. L'exposant, en particulier, signifie qu'il n'est pas une simple traduction de la vitesse d'un motif de bits de droite, le bit de signe pourrait se déplacer à l'exposant, et le bit le moins significatif de l'exposant à un déplacement dans la mantisse, complètement non-évidence des ensembles de significations. Dans la norme IEEE 754, il y a un implicite 1 bits devant de la réelle bits de mantisse, ce qui complique l'interprétation.Des commentaires similaires s'appliquent à l'un des autres bits les opérateurs.
Donc, car il n'est pas sain d'esprit ou utiles à l'interprétation des bits les opérateurs de
double
valeurs, ils ne sont pas autorisés par la norme.De commentaires:
Ce code a été écrit il y a plusieurs années pour SPARC (big-endian) l'architecture.
L'a commenté sur 'image_print()` fonction imprime un ensemble arbitraire d'octets en hexadécimal, avec diverses modifications mineures. Contactez-moi si vous voulez le code (voir mon profil).
Si vous êtes à l'aide d'Intel (little-endian), vous aurez probablement besoin de modifier le code pour traiter l'inverse bits d'ordre. Mais elle montre comment vous pouvez le faire - à l'aide d'un
union
.N'est pas la norme à virgule flottante IEEE-754?
comment se fait-représentation binaire est différent de bits de niveau de structuration? Je ne comprends pas votre commentaire.
<<
et>>
pourrait être défini comme la multiplication et la division par 2, ce qui, pourdouble
signifierait incrémentation/décrémentation de l'exposant de terrain.&
,|
, et^
serait beaucoup moins simple."...il n'est pas sain d'esprit ou utiles à l'interprétation des bits les opérateurs de doubler les valeurs..." Faux. Downvote.
OriginalL'auteur Jonathan Leffler
Vous ne pouvez pas appliquer directement les opérateurs au niveau du bit à
float
oudouble
, mais vous pouvez toujours accéder à l'bits indirectement en mettant la variable dans ununion
avec un tableau de caractères de taille appropriée, puis la lecture de l'bits à partir de ces caractères. Par exemple:Vous pouvez avoir besoin d'ajuster votre routine de travail sur l'omble chevalier, qui, généralement, ne pas aller jusqu'à 4096, et il peut aussi être une certaine étrangeté à l'endianness ici, mais l'idée de base devrait fonctionner. Il ne sera pas compatible multi-plateforme, puisque les machines utilisent différents boutisme et les représentations des doubles, donc attention à la façon dont vous l'utiliser.
OriginalL'auteur templatetypedef
Opérateurs au niveau du bit ne fonctionnent généralement pas avec la "représentation binaire" (aussi appelé représentation d'objet) de tout type. Les opérateurs sur les bits de travail avec valeur de représentation du type, qui est généralement différente de la représentation d'objet. Qui s'applique à
int
ainsi que pourdouble
.Si vous voulez vraiment obtenir à l'intérieur de la représentation binaire d'un objet de n'importe quel type, comme vous l'avez indiqué dans votre question, vous avez besoin de réinterpréter l'objet de ce type comme un tableau de
unsigned char
des objets et de les utiliser les opérateurs au niveau du bit sur cesunsigned char
sPar exemple
Maintenant par l'accès aux éléments
c[0]
parc[sizeof(double) - 1]
vous verrez la représentation interne de typedouble
. Vous pouvez utiliser les opérations bit à bit sur cesunsigned char
valeurs, si vous le souhaitez.Remarque, encore une fois, que dans le cas général, afin d'accéder à la représentation interne de type
int
que vous avez à faire la même chose. Il s'applique généralement à tout type autre quechar
types.OriginalL'auteur AnT
Faire un peu de sages-cast d'un pointeur vers le double de
long long *
et de déréférencement.Exemple:
Edit: Ce n'est presque certainement va aller à l'encontre de gcc est l'application stricte de l'aliasing. Utilisez l'une des solutions différentes. (
memcpy
, les syndicats, les__attribute__((__may_alias__))
, etc)&&
devrait être&
.oups. J'ai besoin de regarder ce que j'remplir =/
sizeof(double) est de 8. C'est 64b. Vous ne savez pas où vous êtes l'obtention 16B.
OriginalL'auteur KitsuneYMG
Autre solution est d'obtenir un pointeur vers la variable à virgule flottante, et de le jeter à un pointeur sur un type entier de la même taille, et ensuite obtenir la valeur de l'entier de ce pointeur pointe. Vous avez maintenant une variable de type entier avec la même représentation binaire comme la virgule flottante, et vous pouvez utiliser votre opérateur au niveau du bit.
Mais rappelez-vous: vous avez à jeter un type avec la même taille. Sinon, des choses imprévisibles peuvent se produire (comme dépassement de la mémoire tampon, de violation d'accès etc.).
Encore mieux: long x = * reinterpret_cast<long *> (& y);
OriginalL'auteur jaboja