2010-07-07 16 views
2

Je souhaite convertir une entrée utilisateur en virgule flottante en son équivalent entier. Je pourrais faire ceci en acceptant une chaîne d'entrée, dites "-1.234" et alors je pourrais juste convertir explicitement chaque caractère à sa représentation décimale. (gros boutiste en passant). Donc, je voudrais juste dire pour l'exemple que j'ai donné,Convertir un flottant en équivalent entier

-1.234 = 1|01111111|00111011111001110110110 

sign bit = 1 = 128<<31 
exponent bits = 01111111 = 127<<23 
mantissa bits = 00111011111001110110110 = 1962934 
decimal equivalent = 1962934 + 127<<23 + 128<<31 

Ceci est assez facile mais difficile à manier. Y a-t-il une meilleure manière de faire cela? Peut-être une sorte de casting que je peux faire?

+0

Que voulez-vous dire par équivalent entier? –

+0

Ouais, un peu flou là, par équivalent, je veux dire l'équivalent entier de la représentation binaire 32 bits d'un nombre à virgule flottante. Quant à mon acceptation, je vais y aller. –

Répondre

3
float a = -1.234; 
int b = *(int*)&a; 

En outre, en C++, il y a cet opérateur de conversion qui ne fait aucun contrôle, reinterpret_cast. C'est probablement mieux ici.

int b = *reinterpret_cast<int*>(&a); 
+0

Magnifique, merci. –

+1

Au moins en g ++, je suis sûr que vous devez désactiver strict-aliasing pour que cela fonctionne toujours. –

7

Une union vous permet d'accéder à la même pièce de mémoire différents types

union floatint 
{ 
    float f; 
    int i; 
} 

floatint fi; 
fi.f=-1.234; 
int i=fi.i; 

Avertissement: vous pouvez obtenir des différences de plate-forme étranges et des choses comme ça à cause de la taille et alighnment, mais puisque vous Si vous faites déjà quelques hypothèses en essayant d'interpréter le flottant comme un int, vous pourrez peut-être vous en sortir. En savoir plus sur les syndicats, je pense que c'est ce que vous allez vouloir.

+0

Ceci est pour la partie "OS" de ma simulation de processeur que je suis en train de concevoir en verilog/C++. J'ai conçu le processeur pour suivre rigoureusement le MIPSI ISA et j'ai également défini l'architecture pour suivre la convention du grand endian, aussi longtemps que je nourris le type d'équivalent entier que j'ai mentionné, je ne pense pas que je doive m'inquiéter de rien d'autre . –

1

La méthode standard pour réinterpréter les modèles de bits consiste à utiliser memcpy. Si je me souviens bien, gcc autorise le type de pointer-casting *(int*)&a en tant qu'extension, mais il n'est pas garanti par le standard, et ne fonctionne pas avec tous les compilateurs. De même, les syndicats ne sont pas garantis de travailler.

#include <stdio.h> 
#include <string.h> 

float f = -1.234; 
int i; 
memcpy(&i, &f, sizeof i); 
printf("bit pattern is: %d\n", i); 

Avec l'optimisation, l'appel à memcpy sera complètement éliminé du code machine généré.

+0

Je sais que c'est une question C++, mais puisque votre réponse peut être lue comme une réponse C, je ferai remarquer que les syndicats ** sont ** garantis de travailler en C. Note de bas de page 82 en C99TC3 leur permet explicitement de faire ce genre de type-jeu défini par l'implémentation. –

0

Dans le cas où vous avez besoin de convertir une valeur simple, sans une variable supplémentaire:

#define float_to_int(f) (*reinterpret_cast<const int*>(&static_cast<const float&>(f))) 
Questions connexes