What does this code do: static union MSVC_EVIL_FLOAT_HACK INFINITY_HACK = {{0x00, 0x00, 0x80, 0x7F}};
#ifndef INFINITY
#ifdef _MSC_VER
union MSVC_EVIL_FLOAT_HACK
{
unsigned __int8开发者_JAVA技巧 Bytes[4];
float Value;
};
static union MSVC_EVIL_FLOAT_HACK INFINITY_HACK = {{0x00, 0x00, 0x80, 0x7F}};
#define INFINITY (INFINITY_HACK.Value)
#endif
I'm currently getting started with the Chipmunk physics engine and found this in a header file
INFINITY is used to set infinite momentum for objects, however I don't understand what this code above does!
It sets INFINITY to the float value represented by the hex bits 0x7f800000, which is +INF
. Visual Studio doesn't define INFINITY for some reason.
The code above effectively defines a floating-point constant with some very specific bytes representation.
Every float
is represented with a set of bytes, but when you define float
constants you're forced to use decimal representation and can't define a constant with value say 0xFFFFFFFF
(I don't know if that constant is a legal float
number).
The code above bypasses that limitation - it first sets a byte array inside the union and then "accesses" the same byte array as if it was a float
number. This by the way is illegal - only the union member previously set can be legally accessed, but it might work on that specific implementation.
It create a variable INFINITY_HACK, of type MSVC_EVIL_FLOAT_HACK. it sets the Bytes array to have values of the respective hex values. It then converts those bytes to a floating-point number (union only allows you to use one of the underlying values within so by referencing .value it is converting the data that INIFITY_HACK points to, to float) by following the IEEE-754 Floating-Point Standard (note that the bytes are taken in reverse) for binary->float conversion.
There's a nice little calculator that can explain it if you don't know how it works: http://babbage.cs.qc.cuny.edu/IEEE-754/32bit.html (if you enter 7F800000, you'll get Infinity, but try entering 4048F5C2 (you'll get close to 3.14) This calculator goes decimal->hex.
Its a way to initialise the memory occupied by a float variable to 0x7f800000. As @Jim says, this is +infinity in the float.
The code is roughly equivalent to:
byte Bytes[4] = { 0x00, 0x00, 0x80, 0x7F };
float Value;
memcpy(&Value, Bytes, 4);
#define INFINITY_HACK (Value)
First the original code defines a union that allows you to manipulate four bytes of memory as either an array of four bytes, or as a single float (which we assume also occupies four bytes):
union MSVC_EVIL_FLOAT_HACK
{
unsigned __int8 Bytes[4];
float Value;
};
Then it allocates an instance of the union named INFINITY_HACK
and sets the values of its Bytes
array to the hex values specified.:
static union MSVC_EVIL_FLOAT_HACK INFINITY_HACK = {{0x00, 0x00, 0x80, 0x7F}};
This has the effect of initialising the float Value field because it also occupies the same memory as the byte array.
Finally it defines a proprocessor constant named INFINITY
as the float value.
精彩评论