Stocker les ints sous forme de flotteurs

Supposons que j’ai une API qui me permet uniquement de stocker des flottants ou des tableaux de flotteurs. Cependant, j’aimerais stocker ici des valeurs entières.

Je comprends (à peu près) que je suis assez d’accord avec une dissortingbution droite allant jusqu’à 2 ^ 23 environ, mais si je veux aller plus haut? Existe-t-il un moyen de tirer parti des 32 bits d’un float et d’être sûr d’obtenir le même numéro?


Pour clarification:

Je fais des opérations sur les nuages ​​de points avec PRMan de Pixar (c’est-à-dire RenderMan). Je peux écrire en C ou C ++ en liaison avec l’API de nuage de points précompilé. PRMan ne doit à aucun moment utiliser ces ressources que je stocke; J’en ai seulement besoin pour me les rendre intactes après avoir exploité d’autres données attachées aux points.

Discutable:

En C, vous pouvez effectuer les opérations suivantes, ce qui est potentiellement dangereux (en raison de règles de pseudonymes ssortingctes):

int i = XXX; float f; *(int *)&f = i; 

et qui repose sur l’hypothèse que sizeof(int) == sizeof(float) .

Moins discutable:

Plus sûr, mais plus long, est le suivant:

 int i = XXX; float f; memcpy(&f, &i, sizeof(int)); 

Cela dépend toujours de la correspondance des tailles de type de données. Cependant, tous les deux ci-dessus supposent que les éléments internes de la bibliothèque que vous utilisez ne feront rien du tout aux données. Par exemple, il n’y aura pas de traitement spécial pour NaN, ni +/- infinity, etc.

Sûr:

Dans un ordre de pensée totalement différent, si vous êtes prêt à gaspiller deux flottants par int, vous pouvez faire quelque chose comme:

 int i = XXX; float f[2] = { (i & 0xFFFF), ((unsigned)i >> 16 }; 

Ce dernier est sûr (sauf quelques hypothèses assez raisonnables sur la taille des flottants et des ints).

Le champ mantisse vous permet de stocker 23 bits. Le champ exposant vous permet de stocker près de 8 bits , sa largeur est de 8 bits avec quelques valeurs réservées. Et il y a un peu de signe.

En évitant les valeurs réservées dans l’exposant, vous pouvez toujours stocker 31 bits de votre choix.

Vous pouvez trouver frexp et ldexp utiles.

Toutes les réponses données ici supposent que vous voulez uniquement utiliser les octets réservés pour le stockage flottant comme emplacement pour stocker un int. Ils ne vous permettront pas d’effectuer une arithmétique sur les valeurs int-encoded-in-float. Si vous voulez que l’arithmétique fonctionne, vous êtes bloqué avec 24,99 bits (c’est-à-dire une plage de – (2 ^ 24-1) à (2 ^ 24-1); je considère que le bit de signe est égal à 0,99 bit plutôt qu’à 1 bit car vous ne peut pas stocker la valeur la plus basse possible avec la représentation signe / magnitude de float) et un ensemble fragmenté de valeurs plus grandes (par exemple, tout multiple entier sur 256 bits de 256 est représentable dans float).