2010-11-04 41 views
7
#ifndef INFINITY 
#ifdef _MSC_VER 
    union MSVC_EVIL_FLOAT_HACK 
    { 
     unsigned __int8 Bytes[4]; 
     float Value; 
    }; 
    static union MSVC_EVIL_FLOAT_HACK INFINITY_HACK = {{0x00, 0x00, 0x80, 0x7F}}; 
    #define INFINITY (INFINITY_HACK.Value) 
#endif 

Yo actualmente estoy comenzar a utilizar el motor de física Chipmunk y encontré esto en un archivo de cabecera¿Qué hace este código?

INFINITY se utiliza para establecer el impulso infinita de objetos, sin embargo, no entiendo lo que este código hace!

Respuesta

6

El código anterior define efectivamente una constante de coma flotante con una representación de bytes muy específica.

Cada float está representado con un conjunto de bytes, pero cuando se define float constantes se ve obligado a utilizar la representación decimal y no se puede definir una constante con valor de decir 0xFFFFFFFF (no sé si eso es una constante número legal float).

El código anterior omite esa limitación: primero establece una matriz de bytes dentro de la unión y luego "accede" a la misma matriz de bytes como si fuera un número float. Esto, por cierto, es ilegal: solo se puede acceder legalmente al miembro del sindicato previamente establecido, pero podría funcionar en esa implementación específica.

15

Establece INFINITY en el valor flotante representado por los bits hexadecimales 0x7f800000, que es +INF. Visual Studio no define INFINITY por algún motivo.

+0

Además, se declara en orden inverso {0x00, 0x00, 0x80, 0x7F} porque x86 usa little-endian. – jfs

+2

¿Eso es '+/- INF' en tu respuesta?Porque estoy bastante seguro de que el patrón de bits es simplemente '+ Inf' :-) – paxdiablo

+0

No importa, lo arreglaré yo mismo. No puedo soportar una respuesta incorrecta con tantos votos :-) – paxdiablo

1

Es una manera de inicializar la memoria ocupada por una variable flotante a 0x7f800000. Como dice @Jim, esto es + infinito en el flotador.

El código es más o menos equivalente a:

byte Bytes[4] = { 0x00, 0x00, 0x80, 0x7F }; 
float Value; 
memcpy(&Value, Bytes, 4); 
#define INFINITY_HACK (Value) 

En primer lugar el código original define una unión que le permite manipular cuatro bytes de memoria, ya sea como un conjunto de cuatro bytes, o como un solo flotador (que nos asumirá también ocupa cuatro bytes):

union MSVC_EVIL_FLOAT_HACK 
    { 
     unsigned __int8 Bytes[4]; 
     float Value; 
    }; 

Luego se asigna una instancia de la unión llamado INFINITY_HACK y establece los valores de su gama Bytes a los valores hexadecimales especificados .:

static union MSVC_EVIL_FLOAT_HACK INFINITY_HACK = {{0x00, 0x00, 0x80, 0x7F}}; 

Esto tiene el efecto de inicializar el campo de valor flotante porque también ocupa la misma memoria que la matriz de bytes.

Por último define una constante proprocessor llamada INFINITY como el valor flotante.

2

Crea una variable INFINITY_HACK, del tipo MSVC_EVIL_FLOAT_HACK. establece la matriz Bytes para tener valores de los respectivos valores hexadecimales. Luego convierte esos bytes a un número de coma flotante (la unión solo le permite usar uno de los valores subyacentes dentro, por lo que al hacer referencia a .value está convirtiendo los datos a los que señala INIFITY_HACK, a flotar) siguiendo el IEEE-754 Floating-Point Standard (tenga en cuenta que los bytes se toman al revés) para la conversión binario-> flotante.

Hay una pequeña calculadora que puede explicar que si usted no sabe cómo funciona: http://babbage.cs.qc.cuny.edu/IEEE-754/32bit.html (si introduce 7F800000, obtendrá infinito, pero intenta entrar 4048F5C2 (que obtendrá cerca de 3.14) This calculator va decimal-> hex