Quiero encasillar un float
como int
. Sin embargo, esto no hace una copia poco a poco. ¿Es posible encasillar un float
en un int
manteniendo todos los bits (signo, exponente, mantisa)?Typecasting by bit copy
Respuesta
La mayoría de los lenguajes permiten algo por el estilo, en C es como:
float f = 3.14f;
int i = *(int*)&f;
¡Esto es maravilloso! ¡Exactamente lo que estoy buscando! –
Aunque esto puede funcionar en la mayoría de los casos, desencadena una advertencia en GCC porque viola el alias estricto, que es un comportamiento técnicamente indefinido. – Mysticial
Eso es interesante, ¿no generó una advertencia en mi GCC (4.4.3)? –
No es posible hacer esto de una manera completamente compatible con C, pero se puede usar sindicatos:
union{
int i;
float f;
} u;
u.f = 123.456; // Your value.
// Read u.i.
Esto debería funcionar en casi todos los sistemas de hoy en día. Y, por supuesto, se supone que float
y int
son del mismo tamaño.
La alternativa es usar el puntero fundido, pero estrictamente hablando, eso viola el alias estricto y se considera un comportamiento indefinido.
Otro (posiblemente sea compatible con - ver comentarios) enfoque es utilizar memcpy()
:
int i;
float f;
f = 123.456; // Your value.
memcpy(&i, &f, sizeof(int));
// Read i
Creo que esto es un comportamiento no especificado (que mencionas en tu primera oración, aunque obtusamente). El Apéndice J1 de C99 dice "Los siguientes no están especificados: ... el valor de un miembro de la unión que no sea el último almacenado en". No especificado se encuentra entre el comportamiento definido por la implementación y el comportamiento indefinido: la implementación no tiene que documentar cómo se realiza una elección en cuanto a cuáles son los resultados. Aún así, no hay otra forma (segura) de hacerlo así que +1. – paxdiablo
Pero hasta donde sé, gcc garantiza que el tipo de juego de palabras por medio de uniones funciona con él, por lo que si no tiene que ser portátil, está bien. –
¿Qué pasa con memcpy? –
Puede usa un union.
union
{
int tmp;
float f;
} u;
u.f = z;
Then u.tmp
es lo mismo bits. (Código tomado de this Wikipedia article).
- 1. Typecasting en C#
- 2. Typecasting en SML
- 3. PHP Typecasting - ¿Bueno o malo?
- 4. puntero typecasting con y sin referencia
- 5. PHP matriz bit a bit
- 6. Reemplazar bit menos significativo con operaciones bit a bit
- 7. Python: aritmética bit a bit sin signo de 32 bit
- 8. Explaining copy constructor example
- 9. template copy constructor
- 10. Dired copy asincronically
- 11. phonegap copy-protection
- 12. Función COPY en PostgreSQL
- 13. html: © no muestra
- 14. Genérico C# Copy Constructor
- 15. operaciones RESTful copy/move?
- 16. C# Shallow copy Dictionary?
- 17. visual studio copy local
- 18. python byRef // copy
- 19. C# Generic Copy Constructor
- 20. Problemas de Typecasting, cómo usar el viejo == en lugar de ===
- 21. C# - Problemas con boxing/unboxing/typecasting ints. No entiendo
- 22. AND bit a bit, bit a bit pregunta Incluido O, en Java
- 23. la realización de una suma bit a bit
- 24. operaciones bit a bit en Postgres
- 25. Operaciones bit a bit con enteros grandes
- 26. Operador bit a bit en SQLAlchemy
- 27. ¿Qué son los operadores bit a bit?
- 28. Operaciones bit a bit en el corto
- 29. operaciones bit a bit sobre no números
- 30. aplicaciones prácticas de operaciones bit a bit
Esto solo puede funcionar si 'sizeof (float) <= sizeof (int)'. No tengo ganas de buscar en Google la respuesta si esto está garantizado por el idioma. –