2010-11-10 16 views
8

Supongamos que tengo una API que solo me permite almacenar flotadores o matrices de flotadores. Sin embargo, me gustaría almacenar valores enteros aquí.Almacenar ints como flotadores

Yo (más o menos) entiendo que estoy bastante bien con un molde directo hasta alrededor de 2^23, pero ¿y si quiero ir más arriba? ¿Hay alguna forma de que pueda aprovechar más de los 32 bits de un flotador y me aseguro de recuperar el mismo número?


Como aclaración:

estoy haciendo algunas operaciones en las nubes de puntos con PRMan de Pixar (es decir, RenderMan.). Puedo escribir en C o C++ vinculando contra la API de nube de puntos precompilada. PRMan en ningún momento tiene que usar estas operaciones que estoy almacenando; Solo necesito que me los devuelvan intactos después de operar con otros datos adjuntos a los puntos.

+2

¿De qué idioma estamos hablando? –

+0

Aclaré un poco. =] –

+0

También es importante tener en cuenta en qué plataforma se encuentra para saber cómo se implementan los flotadores. Pero probablemente sea una apuesta * realmente * segura de que está utilizando flotadores IEEE. –

Respuesta

8

Cuestionable:

En C, puede hacer lo siguiente, que es potencialmente peligroso (debido a las reglas estrictas-aliasing):

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

y que se basa en la suposición de que sizeof(int) == sizeof(float).

menos cuestionable:

más seguro, pero más prolijo, es la siguiente:

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

Esto todavía se basa en la coincidencia de tamaños de tipo de datos. Sin embargo, ambos de los anteriores hacen la suposición de que las partes internas de la biblioteca que está utilizando harán nada en absoluto a los datos. Por ejemplo, no va a tener ningún tratamiento especial para NaN, o +/- infinito, etc.

seguro:

A lo largo de un tren completamente diferente de pensamiento, si estás dispuesto a perder dos flotadores por int, usted podría hacer algo como:

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

Este último es segura (con excepción de algunos supuestos bastante razonables sobre el tamaño de flotadores y enteros).

+1

¿No usarías i >> 16 para f [1]? – MSN

+0

Algunos patrones de bits flotantes están reservados y no se pueden usar. Así que, aunque es posible que pueda escribirlos sobre la parte superior de una variable flotante en la memoria, pasarlos a alguna forma de almacenamiento puede romper el contenedor de almacenamiento de forma impredecible. No tenemos información sobre el almacenamiento y, por lo tanto, no podemos garantizar que esto funcione. –

+0

@Martin: Sí, he aludido a esto en mi respuesta. –

3

El campo mantissa le permite almacenar 23 bits. El campo de exponente le permite almacenar casi 8 bits, tiene 8 bits de ancho con algunos valores reservados. Y hay un poco de señal.

Al evitar los valores reservados en el exponente, aún puede almacenar 31 bits de su elección.

Puede encontrar frexp y ldexp útil.

0

Todas las respuestas dadas aquí asumen que usted solo quiere usar los bytes reservados para el almacenamiento flotante como un lugar para almacenar un int. No le permitirán realizar aritmética en los valores int-encoded-in-float. Si quieres que la aritmética funcione, estás atrapado con 24,99 bits (es decir, un rango de - (2^24-1) a (2^24-1); considero que el bit del signo es de 0,99 bits en lugar de 1 bit porque no puede almacenar el valor más bajo posible con la representación de signo/magnitud de flotante) y un conjunto disperso de valores más grandes (por ejemplo,cualquier múltiplo entero de 32 bits de 256 es representable en float).

+0

Eso debería ser de 24 bits, ¿no? La precisión simple tiene 1 bit de signo y 23 bits de mantisa. –